Spring的IoC和DI-20.02.28

  • IoC的概念和作用
     //private IitemsDao iitemsDao = new ItemsDaoImpl();
      private IitemsDao iitemsDao = (IitemsDao)BeanFactory.getBean("itemsDao");
    
    通过这段代码可以揭露出IoC的含义 : 代表着两种截然不同的创建对象的方式
    • 原来 : 我们在获取对象时,都是采用new的方式,是主动的
      主动
    • 现在 : 我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象,是被动的
      被动
    • 概念 :

      控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
      * 作用 : 削减计算机程序的耦合(解除我们代码中的依赖关系)

  • spring中的loc前期准备
  • spring基于XML的IOC环境搭建和入门
    • 添加依赖
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.3.RELEASE</version>
      <scope>provided</scope>
      </dependency>
    
    • resources目录下新建bean.xml
    <?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">
     <!--        把对象的创建交给Spring来管理-->
      <bean id="itemsService" class="com.qfetu.service.impl.ItemsServiceImpl"></bean>
      <bean id="itemsDao" class="com.qfetu.dao.impl.ItemsDaoImpl"></bean>
     </beans>
    
    • 使用Spring创建对象
    public class ItemsTest {
      /**
      * 获取spring的IoC核心容器,并根据id获取对象
      */
      @Test
      public void findAll(){
     ​
      // 1.获取核心容器对象
      ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      // 2.根据id获取Bean对象
      IitemsService is = (IitemsService) ac.getBean("itemsService");
      IitemsDao id = ac.getBean("itemsDao",IitemsDao.class);
     ​
      System.out.println(is);
      System.out.println(id);
      /* //IitemsService iitemsService = new ItemsServiceImpl();
      IitemsService iitemsService = (IitemsService)BeanFactory.getBean("itemsService");
      List<Items> list = iitemsService.findAll();
     ​
      for (Items items : list) {
      System.out.println(items.getAcctName());
      }*/
      }
     }
    
  • ApplicationContext的三个实现类
    • IDEA查找接口的实现类
      • 选中接口
      • 右击选中Diagrams(Ctrl+Alt+Shift+U)
      • 右击选中Show Implementations(Ctrl+Alt+B)
    • ClassPathXmlApplicationContext ,FileSystemXmlApplicationContext和AnnoationConfigApplicationContext
 * ApplicationContext的三个常用实现类:
  *      ClassPathXmlApplicationContext : 它可以加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话,加载不了
  *      FileSystemXmlApplicationContext : 它可以加载磁盘任意路径下的配置文件(必须由访问权限)
  *      AnnotationConfigApplicationContext : 它是用于读取注解创建容器的
  • BeanFactory和ApplicationContext的区别
 * 核心容器的两个接口引发的问题 :
   *  ApplicationContext :    单例对象适用  采用此接口
   *      它在构建核心容器时,创建对象采取的策略是采用立即加载的方式,也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象
   *  BeanFactory :           多例对象适用
   *      它在构建核心容器时,创建对象采用的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象
   */
  • spring中bean的细节之三种创建Bean对象的方式

    • 第一种方式 : 使用默认构造函数创建
      bean.xml
      在Spring的配置文件中使用bean标签.配以id和class属性之后,且没有其他属性和标签时,
      采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
      ​
       <bean id="itemsService" class="com.qfetu.service.impl.ItemsServiceImpl"></bean>
       <bean id="itemsDao" class="com.qfetu.dao.impl.ItemsDaoImpl"></bean>
      
    • 第二种方式 : 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)
      bean.xml
       <bean id="instanceFactory" class="com.qfetu.Factory.InstanceFactory"></bean>
        <bean id="itemsService" factory-bean="instanceFactory" factory-method="getIitemsService"></bean>
        <bean id="itemsDao" class="com.qfetu.dao.impl.ItemsDaoImpl"></bean>
      
      InstanceFactory.java
               /**
        * 模拟一个工厂类,(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
        */
       public class InstanceFactory {
       ​
        public IitemsService getIitemsService(){
        return new ItemsServiceImpl();
        }
       ​
       }
      
    • 第三种方式 : 第三种方式 : 使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入Spring容器)
      bean.xml
        <bean id="itemsService" class="com.qfetu.Factory.StaticFactory" factory-method="getIitemsService"></bean>
        <bean id="itemsDao" class="com.qfetu.dao.impl.ItemsDaoImpl"></bean>
      
      StaticFactory.java
                /**
        * 模拟一个工厂类,(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
        */
       public class StaticFactory {
       ​
        public static IitemsService getIitemsService(){
        return new ItemsServiceImpl();
        }
       ​
       }
      
  • spring中bean的细节之作用范围

    • bean标签的scope属性 :
      • 作用 : 用于指定bean的作用范围
      • 取值 : 常用singleton和prototype
        • singleton : 单例的 (默认值)
        • prototype : 多例的
        • request : 作用于web应用的请求范围
        • session : 作用于web应用的会话范围
        • global-session : 作用于集群环境的会话范围 (全局会话范围),当不是集群环境时,它就是session
      • global-session的含义


        global-session的作用域
  • spring中bean的细节之生命周期

    • 单例对象
      • 出生 : 当容器创建时对象出生
      • 活着 : 只要容器还在,对象一直活着
      • 死亡 : 单例对象的生命周期和容器相同
    • 多例对象
      • 出生 : 当我们使用对象时Spring框架为我们创建
      • 活着 : 对象只要是在使用过程中就一直活着
      • 死亡 : 当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
    • 栗子
      ItemsServiceImpl.java
       public ItemsServiceImpl(){
       System.out.println("对象创建了");
       }
      ​
       public void init(){
       System.out.println("对象初始化了");
       }
      ​
       public void destroy(){
       System.out.println("对象销毁了");
       }
    

    Test.java

         // 1.获取核心容器对象
        //ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 2.根据id获取Bean对象
        IitemsService is = (IitemsService) ac.getBean("itemsService");
       ​
        //手动关闭容器
        ac.close();
    
    • 单例对象
      bean.xml
           <bean id="itemsService" class="com.qfetu.service.impl.ItemsServiceImpl" scope="singleton"
       init-method="init" destroy-method="destroy"></bean>
    

    运行结果

       对象创建了
       对象初始化了
       对象销毁了
    
    • 多例对象
      bean.xml
    ```
             <bean id="itemsService" class="com.qfetu.service.impl.ItemsServiceImpl" scope="prototype"
      init-method="init" destroy-method="destroy"></bean>
    
    ```
    

    运行结果

      对象创建了
      对象初始化了
    
  • spring的依赖注入

    • 依赖注入 : Dependency Injection
    • IoC的作用 : 降低程序间的耦合(依赖关系)
    • 依赖关系的管理 : 以后都交给Spring来维护,在当前类需要用到其他类的对象,由Spring为我们提供,我们只需要在配置文件中说明
    • 依赖关系的维护 : 就称之为依赖注入
    • 依赖注入 :
      • 能注入的数据 : 有三类
        • 基本类型和String
        • 其他bean类型(在配置文件中或者注解配置过的bean)
        • 复杂类型/集合类型
      • 注入的方式 : 有三种
        • 使用构造函数提供
        • 使用set方法提供
        • 使用注解提供
  • 构造函数注入

    • 使用的标签 : constructor-arg

    • 标签出现的位置 : bean标签的内部

    • 标签中的属性 :

      • type : 用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
      <constructor-arg type="java.lang.String" value="维多利亚少年"></constructor-arg>
      
      • index : 用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置是从0开始
      <constructor-arg index="1" value="18"></constructor-arg>
      
      • name : 用于指定给构造函数中指定名称的参数赋值 常用的
      <constructor-arg name="birthday" ref="date"></constructor-arg>
      

      --------------------------以上三个用于指定给构造函数中的哪个参数赋值---------------------------

      • value : 用于提供基本类型和String类型的数据
       <constructor-arg type="java.lang.String" value="维多利亚少年"></constructor-arg>
       <constructor-arg index="1" value="18"></constructor-arg>
      
      • ref : 用于指定其他的bean类型数据,它指的是在Spring的IoC核心容器中出现过的bean对象
      <constructor-arg name="birthday" ref="date"></constructor-arg>
          ​
      <!--    配置一个日期对象-->
      <bean id="date" class="java.util.Date"></bean>
      
    • 优势 : 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功,加深了印象

    • 弊端 : 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供

  • set方法注入 更常用的方式

    • 涉及的标签 : property
    • 出现的位置 : bean标签的内部
    • 标签的属性 :
      • name : 用于指定注入时所调用的set方法名称
           <property name="name" value="爆豪"></property>
      
      • value : 用于提供基本类型和String类型的数据
      • ref : 用于指定其他的bean类型数据,它指的就是在Spring的IoC核心容器中出现过的bean对象
    • 优势 : 创建对象时没有明确的限制,可以直接使用默认构造函数
    • 弊端 : 如果有某个成员必须有值,则获取对象时有可能set方法没有执行
  • 注入集合数据

    • 复杂类型的注入/集合类型的注入:
      • 用于给List结构的集合注入的标签 :
        • list
        <property name="myList">
        <list>
        <value>ddd</value>
        <value>eee</value>
        <value>fff</value>
        </list>
        </property>
        
        • array
        <property name="myStrs">
        <array>
        <value>aaa</value>
        <value>bbb</value>
        <value>ccc</value>
        </array>
        </property>
        
        • set
        <property name="mySet">
        <set>
        <value>ggg</value>
        <value>hhh</value>
        <value>iii</value>
        </set>
        </property>
        
      • 用于给Map结构的集合注入的标签 :
        • map
          <property name="myMap">
          <map>
          <entry key="111" value="jjj"></entry>
          <entry key="222" value="kkk"></entry>
          <entry key="333" value="lll"></entry>
          </map>
          </property>
        
        • props
          <property name="myProp">
          <props>
          <prop key="444">mmm</prop>
          </props>
          </property>
        
      • 结构相同,标签可以互换
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容