天天看点

Spring---IOC控制反转和依赖注入(xml方式)

Spring—IOC控制反转和依赖注入(xml方式)

  1. IOC的概念:

    1. 控制反转,将创建对象的权力从代码中剥离出来,以其他形式体现,例如配置文件
    2. 使用反射和配置文件的形式创建对象,可以通过调整配置文件,灵活的切换实现类,不需要修改代码,也不需要重新编译,降低了层次跟层次之间的耦合度
  2. 环境的搭建:

    1. 在maven的配置文件中引入依赖
      <dependencies>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>5.0.2.RELEASE</version>
          </dependency>
      </dependencies>
                 
    2. 在resources文件夹下创建xml文件(这里叫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来管理-->
          <!--id就是唯一标识 class就是要创建类的全限定类名-->
          <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean>
      
          <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
      </beans>
                 
    3. 进行类的创建
      /**
       * 模拟一个表现层,用于调用业务层
       */
      public class Client {
      
            /**
           * 获取spring的ioc核定容器,并根据id获取对象
           *
           * ApplicationContext的三种常用实现类
           *      ClassPathXmlApplicationContext:可以加载类路径下的配置文件,要求配置文件必须在类路径中
           *      FileSystemXmlApplicationContext:可以加载磁盘任意路径下的配置文件(必须有访问权限)
           *      AnnotationConfigApplicationContext:用于读取注解来创建配置文件的
           *
           * 核心容器的两个接口引发的问题:
           *      ApplicationContext:单例对象适用,更多使用此接口
           *          它在构建核心容器时,创建对象采取的策略的采用立即加载的方式,只要一读取完配置文件马上就创建配置文件中配置的对象
           *      BeanFactory:多例对象适用
           *          它在构建核心容器时,创建对象采取的策略的是采用延迟加载的方式,什么时候根据id获取对象了什么时候才创建对象
           * @param args
           */
          public static void main(String[] args) {
              //获取核心容器对象,参数指定配置文件的位置
              ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
              /*
              根据id获取bean对象()两种方式
              * */
              //方式1:强转成service层的对象
              IAccountService as = (IAccountService) ac.getBean("accountService");
              //方式2:传入service层类的字节码文件,就不用强转了
              IAccountDao ad = ac.getBean("accountDao", IAccountDao.class);
      
          }
      }
                 
  3. spring对bean管理的细节

    1. 创建bean的三种方式
      1. <!--方式1:使用默认构造函数创建
                         在spring文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
                         采用的就是默认构造函数创建对象,如果类中没有默认的构造函数,则创建类失败
            -->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean>
                   
      2. <!--方式2:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器中)
                       class就是该工厂的全限定类名,factory-bean就是第一行bean的id,factory-method时该工厂中的方法名
            -->
        <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
        <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService()"> </bean>
                   
      3. <!--方式3:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器中)
            class就是该工厂的全限定类名,factory-method时该工厂中的方法名
            -->
        <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService()"> </bean>
                   
    2. bean对象的作用范围
      <!--bean标签的作用范围
              bean标签的scope属性
                  作用:用于指定bean的作用范围
                  取值:常用的就是单例的和多例的
                      singleton:单例的(默认值)
                      prototype:多例的
                      request:作用于web的请求范围
                      session:作用于web的会话范围
                      global-session:作用域集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
          -->
      <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="singleton"> </bean>
                 
    3. bean对象的生命周期
      <!--bean标签的生命周期
              单例对象
                  出生:当容器创建时出生
                  活着:只要容器还在,对象就一直活着
                  死亡:容器销毁,对象销毁
                  总结:单例对象的生命周期和容器相同
              多例对象
                  出生:当我们使用对象时,spring框架进行创建对象
                  活着:对象只要一直使用就活着
                  死亡:对象长时间不使用,且没有别的对象引用时,由java垃圾回收机制回收
          -->
                 
  4. spring依赖注入(Dependency Injection)

    1. 概念:ioc为了降低程序之间的耦合(依赖关系),依赖关系之间的维护就称之为依赖注入
    2. 依赖注入的方式:(如果是经常变化的数据,并不适用于注入的方式)
      <!--
              依赖注入:
                  能注入的数据:有三类
                      基本数据类型和String
                      其它bean类型(在配置文件中或注解配置的bean)
                      复杂类型/集合类型
                  注入的方式:有三种
                      使用构造函数
                      使用set方法
                      使用注解
         -->
                 
      1. 使用构造函数注入
        <!--构造函数的注入:
                    使用的标签:constructor-arg
                    标签的位置:bean标签中
                    标签中的属性:
                        type:用于指定要注入的数据的类型,该数据的类型也是构造函数中某个或某个参数的类型
                        index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引从0开始
                        name:用于指定给构造函数中的指定名称赋值
                        =========================以上三个用于指定给构造函数中的哪个参数赋值===============================
                        value:用于提供基本类型和String类型的数据
                        ref:用于指定其它bean类型数据,它指的是在spring的ioc核心文件中出现的bean对象
        
                    优势:在获取没有空参构造的bean对象时,注入数据是必须的操作,否则对象无法创建成功
                    弊端:改变了bean的实力化方式,是我们如果用不到这些数据页必须提供(不能写null)
            -->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
            <constructor-arg name="name" value="张三"></constructor-arg>
            <constructor-arg name="age" value="18"></constructor-arg>
            <constructor-arg name="birthday" ref="now"></constructor-arg>
        </bean>
        <!--使用spring配置Date的bean,获取当前时间-->
        <bean id="now" class="java.util.Date"></bean>
                   
      2. 使用set方式注入
        <!--set方式注入(比构造函数注入常用)
                   使用的标签:property
                   标签的位置:bean标签中
                   标签中的属性:
                        name:用于指定注入时所调用的set的方法名称(去掉方法名的set并将首字母改为小写;如setName&ndash;&gt;name)
                        value:用于提供基本类型和String类型的数据
                        ref:用于指定其它bean类型数据,它指的是在spring的ioc核心文件中出现的bean对象
                   优势:创建对象时没有明确的限制,可以直接使用默认构造函数
                   弊端:如果有某个成员必须有值,则获取对象时有可能set方法没有执行
            -->
        
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
            <property name="name" value="王五"></property>
            <property name="age" value="19"></property>
            <property name="birthday" ref="now"></property>
        </bean>
        <!--使用spring配置Date的bean,获取当前时间-->
        <bean id="now" class="java.util.Date"></bean>
                   
    3. 注入集合数据
      <!--复杂类型/集合类型的注入,
                  用于给List结构注入的标签
                      list array set
                  用于给map结构注入的标签
                      map props
          -->
      <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
          <!--给数组类型注入-->
          <property name="myStrs">
              <array>
                  <value>AA</value>
                  <value>BB</value>
                  <value>CC</value>
              </array>
          </property>
      
          <!--给List类型注入-->
          <property name="myList">
              <list>
                  <value>AA</value>
                  <value>BB</value>
                  <value>CC</value>
              </list>
          </property>
      
          <!--给Set类型注入-->
          <property name="mySet">
              <set>
                  <value>AA</value>
                  <value>BB</value>
                  <value>CC</value>
              </set>
          </property>
      
          <!--给Map类型注入-->
          <property name="myMap">
              <map>
                  <entry key="testA" value="AA"></entry>
                  <entry key="testB">
                      <value>BB</value>
                  </entry>
              </map>
          </property>
      
          <!--给properties类型注入-->
          <property name="myPros">
              <props>
                  <prop key="testA"></prop>
                  <prop key="testB"></prop>
              </props>
          </property>
      </bean>
                 

继续阅读