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>
        
      • 结构相同,标签可以互换
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容