Spring学习笔记(一)

简介: Spring学习笔记

Spring

说明下【本文是在网上听课做的笔记,代码是自己敲的,有些文字是复制的老师发的】

Spring框架介绍

Spring是一个轻量级的IoC和AOP的框架

IoC

控制反转

AOP

面向切面编程

Spring的功能

优点:

1)方便解耦,简化开发

Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。

2)方便集成各种优秀框架

Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis

等)的直接支持。

3)降低 Java EE API 的使用难度

Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些

API 应用的难度大大降低。

4)方便程序的测试

Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。

5)AOP 编程的支持

Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。

6)声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无须手动编程。

接口和Spring 是完美搭配

以前

public interface UserDAO{
    void save();
}
public class UserDAOImpl implements UserDAO{
    public void save(){
        ....
    }
}
public class UserServiceImpl implements UserService{
    private UserDAO userDAO = new UserDAOImpl();
    public void reg(){
        userDAO.save();
    }
}
----------------------------------------------------
public class UserDAOJDBCImpl implements UserDAO{
  public void save(){
    ....
  }
}
public class UserServiceImpl implements UserService{
    private UserDAO userDAO;
    public void reg(){
        userDAO.save();
        ....
    }
}
我们在UserServiceImpl中不再实例化DAO对象
从Spring容器中获得   

搭建Spring环境

1、添加依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.18.RELEASE</version>  
</dependency>

2、编写bean

package cn.cqie.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String uname;
    private String upwd;
}

3、编写配置文件

先将模板在idea中生成

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        User user = new User();
        <bean>  声明实例化对象的信息
        id  对象的名称
        class 对象的类型
    -->
    <bean id="user" class="cn.cqie.pojo.User"></bean>
</beans>

4、测试获取user对象

package cn.cqie.test;
import cn.cqie.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
    @Test
    public void test(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("app.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println("AppTest.test"+user);
        user.setUname("yx");
        user.setUpwd("123");
        System.out.println(user);
    }
}

IOC容器介绍

BeanFactory

在没有获取容器中实例时,不实例化对应的对象

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("app.xml"));
BeanFactory beanFactory1 = new XmlBeanFactory(new FileSystemResource("d:/app.xml"));

ApplicationContext

ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("d:/app.xml");
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
ApplicationContext applicationContext3 = new AnnotationConfigApplicationContext(JavaConfig.class);
User user = (User) applicationContext3.getBean("user");
System.out.println("AppTest.test"+user);
user.setUname("yx");
user.setUpwd("123");
System.out.println(user);

容器生成时,就会实例化配置文件中声明的对象

ApplicationContext从BeanFactory派生出来的

ApplicationContext增加了以下功能

  1. 国际化(MessageSource)
  2. 访问资源,如URL和文件(ResourceLoader)
  3. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
  4. 消息发送、响应机制(ApplicationEventPublisher)
  5. AOP(拦截器)

获取实例的简单的底层原理

package cn.cqie.util;
import cn.cqie.pojo.User;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyClassPathXmlApplicationContext {
    Map<String,Object> container = new HashMap<>();
    public MyClassPathXmlApplicationContext(String resource){
        //获得resource对应的文件路径 或者 输入流
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(new File(resource));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //使用xml 解析技术(dom4j)读取xml文件的信息
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(inputStream);
            //读出标签<bean>、属性(id 、 class) 及值 (user 、 cn.cqie.pojo.User)
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element:elements){
                System.out.println(element.getName());
                List<Attribute> attributes = element.attributes();
                String id = "";
                String clazz = "";
                for (Attribute attribute:attributes){
                    if(attribute.getName().equals("id")){
                        id = attribute.getValue();
                        System.out.println("id :"+id);
                    }else{
                        if(attribute.getName().equals("class")){
                            clazz = attribute.getValue();
                            System.out.println("clazz :"+ clazz);
                        }
                    }
                }
                //使用反射生成实例
                Class<?> aClass = Class.forName(clazz);
                Object obj = aClass.newInstance();
                //使用Map存储id和对应的实例
                container.put(id,obj);
            }
        } catch (DocumentException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public Object getBean(String id){
        return container.get(id);
    }
    public static void main(String[] args) {
        MyClassPathXmlApplicationContext context = new MyClassPathXmlApplicationContext("f:/app2.xml");
        User user = (User) context.getBean("user");
        user.setUname("tcx");
        System.out.println("user :"+user);
    }
}

Bean的概念

Spring中Bean就是一个类的实例

<bean id="" class="" />

Bean的生成方式有三种:

1、构造器生成

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    通过构造器生成
    cn.cqie.pojo.User 必须有为空的构造器
-->
    <bean id="user" class="cn.cqie.pojo.User"/>
</beans>
@Test
    public void testConstructor(){
        System.out.println(66);
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user = (User) applicationContext.getBean("user");
        user.setUname("constructor  ");
        System.out.println(user);
    }

2、静态工厂

//UserStaticFactor.java
package cn.cqie.util;
import cn.cqie.pojo.User;
public class UserStaticFactor {
    public static User getUser(){
        return new User();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--        通过静态工厂生成
      User user = UserStaticFactor.getUser();
-->
    <bean id="user2" class="cn.cqie.util.UserStaticFactor" factory-method="getUser"/>
</beans>
@Test
    public void testStaticFactor(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user2 = (User) applicationContext.getBean("user2");
        user2.setUname("static factory");
        System.out.println(user2);
    }

3、实例工厂

//  UserInstanceFactor.java
package cn.cqie.util;
import cn.cqie.pojo.User;
public class UserInstanceFactor {
    public User getUser(){
        return new User();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    实例化工厂构造
  UserInstanceFactor userInstanceFactor = new UserInstanceFactor();
    User user = userInstanceFactor.getUser();
-->
    <bean id="userInstanceFactor" class="cn.cqie.util.UserInstanceFactor" />
    <bean id="user3" factory-bean="userInstanceFactor" factory-method="getUser"/>
</beans>
@Test
    public void testInstanceFactor(){
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user3 = (User) applicationContext.getBean("user3");
        user3.setUname("Instance factor ");
    }

Bean的作用域范围

scope有如下五个取值:

singleton:单例的(默认的),使用singleton定义的Bean是单例的,每次调用getBean都是调用的同一个对象。只要IoC容器一创建就会创建Bean的实例。

prototype:多例的,每次通过Spring IoC容器获取prototype定义的Bean时,容器都将创建一个新的Bean实例。创建时不会实例该Bean,只有调用getBean方法时,才会实例化。

request:作用于web的请求范围,在每一次HTTP请求时,容器会返回Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Request内有效。

session:作用于web的会话范围,在一次HTTP Session中,容器会返回该Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Session内有效。

global-session:作用于集群环境的会话范围(全局会话范围),在一个全局的HTTP Session中,容器返回Bean的同一个实例。当不是集群环境时,它就是session。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    通过构造器生成-->
    <bean id="user" class="cn.cqie.pojo.User" scope="prototype"/>
</beans>
@Test
    public void testScope(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app3.xml");
        User user = (User) applicationContext.getBean("user");
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user==user2);
    }

依赖注入概述

dao层和service层 impl代码

package cn.cqie.dao.impl;
import cn.cqie.dao.UserDAO;
public class UserDAOImpl implements UserDAO {
    @Override
    public void save() {
        System.out.println("UserDAOImpl.save");
    }
}
package cn.cqie.service.impl;
import cn.cqie.dao.UserDAO;
import cn.cqie.pojo.User;
import cn.cqie.service.UserService;
public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
    //setter注入
    public void setUserDAO(UserDAO userDAO){
        this.userDAO=userDAO;
    }
    public UserServiceImpl(){
    }
    //构造器注入
    public UserServiceImpl(UserDAO userDAO){
        this.userDAO=userDAO;
    }
    @Override
    public void save() {
        System.out.println("UserServiceImpl.save");
        userDAO.save();
    }
}

Setter注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
      DI  依赖注入
      UserDAO userDAO = new UserDAOImpl();
      UserService userService = new UserServiceImpl();
      这时需要通过setter或者构造器注入
      1、setter注入
  -->
    <bean id="userDAO" class="cn.cqie.dao.impl.UserDAOImpl"/>
    <bean id="userService1" class="cn.cqie.service.impl.UserServiceImpl">
        <property name="userDAO" ref="userDAO"/>
    </bean>
</beans>
@Test
public void testSetterDI(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app4.xml");
    UserService userService1 = (UserService) applicationContext.getBean("userService1");
    userService1.save();
}

构造器注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
       2、构造器注入
   -->
    <bean id="userDAO2" class="cn.cqie.dao.impl.UserDAOImpl"/>
    <bean id="userService2" class="cn.cqie.service.impl.UserServiceImpl">
        <constructor-arg name="userDAO" ref="userDAO2"/>
    </bean>
</beans>
@Test
public void testConstructorDI(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app4.xml");
    UserServiceImpl userService2 = (UserServiceImpl) applicationContext.getBean("userService2");
    userService2.save();
}

命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        命名空间注入
        本质还是setter和构造器注入,只是换了种方式
    -->
    <bean id="userDAO3" class="cn.cqie.dao.impl.UserDAOImpl"/>
    <bean id="userService3" class="cn.cqie.service.impl.UserServiceImpl" c:userDAO-ref="userDAO3"
          p:userDAO-ref="userDAO3"/>
</beans>


相关文章
|
5月前
|
XML 存储 Java
Spring 6(一)【Spring 入门】
Spring 6(一)【Spring 入门】
|
6月前
|
XML Java 数据格式
Spring 学习笔记(二)
Spring 学习笔记(二)
30 0
|
6月前
|
前端开发 Java Maven
Spring学习笔记
Spring学习笔记
109 0
|
XML 安全 Java
|
XML Java 数据库连接
|
XML Java 关系型数据库
|
XML Java 数据格式
day1 Spring学习笔记
day1 Spring学习笔记
51 0