• Spring IOC复习与回顾


    IOC
    1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂,DI(依赖注入)是IOC思想的具体实现

    2. Spring提供IOC容器实现的两种方式:

      • BeanFactory:IOC容器的基本实现方式,是Spring内部的使用接口,不提供开发人员使用

        加载配置文件时候不会创建对象,在获取对象时采取创建对象

      • ApplicatioContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用

        加载配置文件的时候就会把配置文件中的对象进行创建

    3. Bean的作用域

      Spring中Bean默认是单例的,表示对IOC容器中的同一个Bean多次getBean得到的是同一个实例:

         @Test
          public void testStu(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
              Stu stu = (Stu) context.getBean("stu");
              Stu stu2 = (Stu) context.getBean("stu");
              System.out.println(stu);  //com.dxy.spring5.Stu@17776a8
              System.out.println(stu2); //com.dxy.spring5.Stu@17776a8
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      当然我们可以通过bean中 scope=”prototype“ 属性设置为多例

      <bean id="stu" class="com.dxy.spring5.Stu" scope="prototype">bean>
      
      • 1

      修改后得到的输出为

      @Test
          public void testStu(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
              Stu stu = (Stu) context.getBean("stu");
              Stu stu2 = (Stu) context.getBean("stu");
              System.out.println(stu);  //com.dxy.spring5.Stu@17776a8
              System.out.println(stu2); //com.dxy.spring5.Stu@69a10787
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      除此之外,singleton与prototype还有以下区别:

      scope值设置为singleton时,在加载spring配置文件的时候就会创建对象

      scope值设置为prototype时,不会在加载spring配置文件的时候创建对象,而是在调用getBean方法时创建对象(每调一次就会创建一个全新的实例)

    4. Bean的生命周期

      ①通过构造器创建bean实例(无参构造)

      ②为bean 的属性设置值和对其他bean的引用(调用set方法)

      ③调用bean 的初始化方法(需要进行配置初始化的方法)

      ④bean可以使用了(对象获取到了)

      ⑤当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

      如果考虑bean的后置处理器,则bean完整的生命周期应该为七步

      ①通过构造器创建bean实例(无参构造)

      ②为bean 的属性设置值和对其他bean的引用(调用set方法)

      ③把bean实例传递给bean后置处理器的方法postProcessBeforeInitialization

      ④调用bean 的初始化方法(需要进行配置初始化的方法)

      ⑤把bean实例传递给bean后置处理器的方法postProcessAfterInitialization

      ⑥bean可以使用了(对象获取到了)

      ⑦当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

    5. Bean管理

      Bean管理指的是两个操作:①Spring创建对象;②Spring注入属性

      Bean管理操作有两种方式:①基于xml配置文件方式实现;②基于注解方式实现

      基于xml的实现方式

      
      <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"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      
      
          <bean id="user" class="com.dxy.spring5.User">
              <property name="userName" value="zhangsan">property>
          bean>
      
      
          <bean id="user1" class="com.dxy.spring5.User" p:userName="lisi">bean>
      
      
          <bean id="order" class="com.dxy.spring5.Orders">
              <constructor-arg name="oname" value="box">constructor-arg>
              <constructor-arg name="address" value="China">constructor-arg>
          bean>
      
          <bean id="user2" class="com.dxy.spring5.User">
              <property name="userName" value="zhangsan">property>
              <property name="orders" ref="order">property>
              
              <property name="orders.oname" value="bottle">property>
          bean>
      
      
          <bean id="user3" class="com.dxy.spring5.User">
              
              <property name="userName" value="zhangsan">property>
              <property name="orders">
                  <bean id="order1" class="com.dxy.spring5.Orders">
                      <constructor-arg name="oname" value="computer">constructor-arg>
                      <constructor-arg name="address" value="China">constructor-arg>
                  bean>
              property>
          bean>
      
      beans>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45

      集合的属性注入

      
      <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:util="http://www.springframework.org/schema/util"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd
                                 http://www.springframework.org/schema/util
                                 http://www.springframework.org/schema/util/spring-util-4.0.xsd">
      
          <bean id="stu" class="com.dxy.spring5.Stu">
              
              <property name="courses">
                  <array>
                      <value>数学value>
                      <value>语文value>
                      <value>历史value>
                  array>
              property>
      
              
              <property name="books" >
                  <list>
                      <ref bean="book1">ref>
                      <ref bean="book2">ref>
                  list>
              property>
      
              
      
      
              
              <property name="numbers">
                  <map>
                      <entry key="zhangsan" value="001">entry>
                      <entry key="lisi" value="002">entry>
                  map>
              property>
      
          bean>
      
          <util:list id="bookList">
              <ref bean="book1">ref>
              <ref bean="book2">ref>
          util:list>
      
          <bean id="book1" class="com.dxy.spring5.Book">
              <property name="bookName" value="Java并发编程">property>
          bean>
          <bean id="book2" class="com.dxy.spring5.Book">
              <property name="bookName" value="深入理解Java虚拟机">property>
          bean>
      beans>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53

      用的实体类:

      User类

      package com.dxy.spring5;
      
      /**
       * Description: 
      * date: 2022/11/15 18:42 * * @author dxy * @since JDK 1.8 */
      public class User { private String userName; private Orders orders; public void setUserName(String name){ this.userName=name; } public void setOrders(Orders orders) { this.orders = orders; } public Orders getOrders() { return orders; } @Override public String toString() { return "User{" + "userName='" + userName + '\'' + ", orders=" + orders + '}'; } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35

      Orders类

      package com.dxy.spring5;
      
      /**
       * Description: 
      * date: 2022/11/15 19:24 * * @author dxy * @since JDK 1.8 */
      public class Orders { private String oname; private String address; public Orders(String oname, String address) { this.oname = oname; this.address = address; } public void setOname(String oname) { this.oname = oname; } @Override public String toString() { return "Orders{" + "oname='" + oname + '\'' + ", address='" + address + '\'' + '}'; } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31

      Stu类

      package com.dxy.spring5;
      
      import java.util.Arrays;
      import java.util.List;
      import java.util.Map;
      
      /**
       * Description: 
      * date: 2022/11/15 20:43 * * @author dxy * @since JDK 1.8 */
      public class Stu { private String[] courses; private List<Book> books; private Map<String,Integer> numbers; public void setCourses(String[] courses) { this.courses = courses; } public void setBooks(List<Book> books) { this.books = books; } public void setNumbers(Map<String, Integer> numbers) { this.numbers = numbers; } @Override public String toString() { return "Stu{" + "courses=" + Arrays.toString(courses) + ", books=" + books+ ", numbers=" + numbers + '}'; } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39

      Book类

      package com.dxy.spring5;
      
      /**
       * Description: 
      * date: 2022/11/15 20:46 * * @author dxy * @since JDK 1.8 */
      public class Book { private String bookName; public void setBookName(String bookName) { this.bookName = bookName; } @Override public String toString() { return "Book{" + "bookName='" + bookName + '\'' + '}'; } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24

      用于测试的类:

      TestSpring5

      package com.dxy.spring5.testdemo;
      
      import com.dxy.spring5.Orders;
      import com.dxy.spring5.Stu;
      import com.dxy.spring5.User;
      import org.junit.Test;
      import org.springframework.beans.factory.BeanFactory;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      /**
       * Description: 
      * date: 2022/11/15 18:31 * * @author dxy * @since JDK 1.8 */
      public class TestSpring5 { @Test public void testStu(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); Stu stu = (Stu) context.getBean("stu"); System.out.println(stu); } @Test public void testAdd(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); User user = (User)context.getBean("user2"); Orders order = (Orders) context.getBean("order"); System.out.println(user.toString()); } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35

      以上我们都是进行手动装配的,即在bean中指定属性以及我们要设置的值,下面我们介绍一下Spring的自动装配

      自动装配:根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入

      在xml中演示自动装配

      基于byName的自动装配:(在bean中设置autowire=“byName”,此时会根据属性名称来寻找对应id的bean,并将属性值注入)

      
      <bean id="user" class="com.dxy.spring5.User" autowire="byName">
              <property name="userName" value="zhangsan">property>
          bean>
      
          <bean id="orders" class="com.dxy.spring5.Orders">
              <constructor-arg name="oname" value="box">constructor-arg>
              <constructor-arg name="address" value="China">constructor-arg>
          bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      运行测试类中得到:

      User{userName='zhangsan', orders=Orders{oname='box', address='China'}}
      
      • 1

      基于byType的自动装配:在bean中设置autowire=“byType”,此时会根据属性的类型来寻找对应class的bean,并将属性值注入)

      <bean id="user" class="com.dxy.spring5.User" autowire="byType">
              <property name="userName" value="zhangsan">property>
          bean>
      
          <bean id="orders" class="com.dxy.spring5.Orders">
              <constructor-arg name="oname" value="box">constructor-arg>
              <constructor-arg name="address" value="China">constructor-arg>
          bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      我们可以得到相同的输出结果。但需要特别注意的是,如果有多个类型相同的bean,我们就不能使用byType来进行自动装配了!

      基于注解的实现方式

      使用注解的目的:简化xml配置

      Spring针对Bean管理中创建对象提供注解:@Component @Service @Controoler @Repository

      上面四个注解功能一致,都可以创建bean实例,只不过我们习惯在不同的层上使用不同的注解,是开发更加规范

      我们先引入了context空间,然后开启组件扫描

      
      <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:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      
      
              
          <context:component-scan base-package="com.dxy">context:component-scan>
      beans>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      创建UserService类,使用注解实现Spring创建对象:

      package com.dxy.spring5.service;
      
      import org.springframework.stereotype.Service;
      
      /**
       * Description: 
      * date: 2022/11/16 10:30 * * @author dxy * @since JDK 1.8 */
      //注解中value属性值可以不写,默认值是类名称首字母小写 @Service(value = "userService") //等价于 public class UserService { public void print(){ System.out.println("test..."); } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      @Test
          public void testUserService(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
              UserService userService = (UserService) context.getBean("userService");
              userService.print(); 
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      使用注解方式实现属性注入:

      @Autowired:根据属性类型进行自动装配 (使用最多)

      @Qualifier:根据属性名称进行注入,使用@Qualifier时需要和@Autowired一起使用

      @Resource:既可以根据类型注入(使用@Resource),也可以根据名称注入 (使用@Resource(name=“xxx”))

      @Value:可以注入普通属性

      package com.dxy.spring5.service;
      
      import com.dxy.spring5.dao.UserDao;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      /**
       * Description: 
      * date: 2022/11/16 10:30 * * @author dxy * @since JDK 1.8 */
      //注解中value属性值可以不写,默认值是类名称首字母小写 @Service(value = "userService") //等价于 public class UserService { //在service中注入dao对象,添加注入属性注解 @Autowired private UserDao userDao; public void print(){ System.out.println("test..."); userDao.print(); } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      UserDao

      package com.dxy.spring5.dao;
      
      /**
       * Description: 
      * date: 2022/11/16 10:47 * * @author dxy * @since JDK 1.8 */
      public interface UserDao { public void print(); }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      UserDaoImpl

      package com.dxy.spring5.dao;
      
      import org.springframework.stereotype.Repository;
      
      /**
       * Description: 
      * date: 2022/11/16 10:47 * * @author dxy * @since JDK 1.8 */
      @Repository public class UserDaoImpl implements UserDao{ public void print() { System.out.println("dao test..."); } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      完全注解开发

      创建配置类,替代xml配置文件

      package com.dxy.spring5.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      
      /**
       * Description: 
      * date: 2022/11/16 11:03 * * @author dxy * @since JDK 1.8 */
      @Configuration //作为配置类,替代xml配置文件 @ComponentScan(basePackages = {"com.dxy"}) public class SpringConfig { }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      测试时也有点变化:

       @Test
          public void testUserService1(){
              //加载配置类
              ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
              UserService userService = (UserService) context.getBean("userService");
              userService.print();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
  • 相关阅读:
    用CMake编译项目 & CMake和g++的区别
    【算法】【递归与动态规划模块】矩阵的最小路径和
    【元宇宙】NFT ,数字货币的未来
    微服务04-Gateway网关
    基于PHP+MySQL的小型企业客户关系管理系统
    Oralce ORA-00018超出最大会话数处理记录
    SQL Server实战七:自定义数据类型、标量值、内嵌表值、多语句表值函数的操作
    PID控制原理基本介绍(图解)
    NFT Insider #64:电商巨头eBay提交NFT相关商标申请,毕马威将在Web3和元宇宙中投入3000万美元
    Python 项目一 数据可视化 01
  • 原文地址:https://blog.csdn.net/qq_43600941/article/details/127881529