Spring第三篇_IOC概念和Spring中的IOC

15 篇文章 0 订阅

3. IOC概念和Spring中的IOC

3.1 IOC的概念

控制反转(Inversion of Control , 英文缩写为IOC) 包创建对象的权力交给框架,是框架的重要特征,并非面向对象编程的专用术语; 它包括依赖注入(Dependency Injection, 简称DI)和依赖查找(Dependency Lookup)

3.2 IOC的作用

​ IOC的作用: 削减计算机程序的耦合(降低代码中的依赖关系)

3.3 Spring中基于XML的IOC环境搭建

  1. 创建day01_eesy_03spring项目

  2. 在pox.xml文件中完成与Spring有关配置 , 导入Spring框架所需要的jar包

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.itheima</groupId>
        <artifactId>day01_eesy_03spring</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <packaging>jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.4.RELEASE</version>
            </dependency>
        </dependencies>
    
    </project>
    
  3. 将day01_eesy_02factory项目下的src/main目录下的文件都复制到day01_eesy_03spring项目的src/main目录下

  4. 创建配置文件bean.xml, 并完成spring相关配置,把创建对象的任务交给Spring管理

    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="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
        <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
    </beans>
    
    
  5. 在模拟表现层Cilent.java中进行配置

    Client.java

    //模拟一个表现层,用于调用业务层
    public class Client {
    
        /**
         * 获取spring的IOC核心容器,并根据id获取对象
         * @param args
         */
    
        public static void main(String[] args) {
            //1.获取核心容器对象
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
            //2.根据id获取bean对象
            IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
            IAccountDao accountDao = applicationContext.getBean("accountDao",IAccountDao.class);
    
            System.out.println(accountService);
            System.out.println(accountDao);
        }
    }
    
  6. 运行结果
    在这里插入图片描述

  7. 目录结构

在这里插入图片描述

3.4 ApplicationContext的三个实现类

  1. ClassPathXmlApplicationContext

    他可以加载类路径下的配置文件,要求配置文件必须在类路径下, 不在的话,加载不了

  2. FileSystemXmlApplicationContext

    他可以加载磁盘任意路径下配置文件(必须有访问权限)

    • 应用:

      Client.java

      //模拟一个表现层,用于调用业务层
      public class Client {
      
          /**
           * 获取spring的IOC核心容器,并根据id获取对象
           *
           * ApplicationContext的三个常用实现类:
           *      ClassPathXmlApplicationContext: 他可以加载类路径下的配置文件,要求配置文件必须在类路径下, 不在的话,加载不了
           *      FileSystemXmlApplicationContext: 他可以加载磁盘任意路径下的配置文件(必须有访问权限)
           *      AnnotationConfigApplicationContext: 它适用于读取注解创建容器的(是明天的内容)
           * @param args
           */
      
          public static void main(String[] args) {
              //1.获取核心容器对象
              //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
              ApplicationContext applicationContext= new FileSystemXmlApplicationContext("D:\\IDEA\\SSM\\Spring\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");
      
              //2.根据id获取bean对象
              IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
              IAccountDao accountDao = applicationContext.getBean("accountDao",IAccountDao.class);
      
              System.out.println(accountService);
              System.out.println(accountDao);
          }
      }
      
  3. AnnotationConfigApplicationContext

    它适用于读取注解创建容器的(是明天的内容)

3.5 BeanFactory和ApplicationContext的区别

3.5.1 核心容器的两个接口引发的问题

ApplicationContext:
他在构建核心容器时, 创建对象采取的策略是采用立即加载的方式,也就额是说,只要一读取配置文件法伤就创建配置文件中配置的对象
BeanFactory:
他在构建核心容器时,创建对象采取的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象

3.5.2 结论

单例对象多使用ApplicationContext, 多例对象多使用BeanFactory, 现在多使用ApplicationContext, ApplicationContext能够自动判断是创建单例对象还是多例对象

3.5.3 案例
  1. 在模拟表现层中Client.java进行ApplicationContext接口的演练

    //模拟一个表现层,用于调用业务层
    public class Client {
    
        /**
         * 获取spring的IOC核心容器,并根据id获取对象
         *
         * ApplicationContext的三个常用实现类:
         *      ClassPathXmlApplicationContext: 他可以加载类路径下的配置文件,要求配置文件必须在类路径下, 不在的话,加载不了
         *      FileSystemXmlApplicationContext: 他可以加载磁盘任意路径下的配置文件(必须有访问权限)
         *      AnnotationConfigApplicationContext: 它适用于读取注解创建容器的(是明天的内容)
         *
         * 核心容器的两个接口引发的问题:
         *      ApplicationContext:             单例对象适用      更多采用此接口
         *          他在构建核心容器时, 创建对象采取的策略是采用立即加载的方式,也就额是说,只要一读取配置文件法伤就创建配置文件中配置的对象
         *      BeanFactory:                    多例对象适用
         *          他在构建核心容器时,创建对象采取的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象
         * @param args
         */
    
        public static void main(String[] args) {
            //1.获取核心容器对象
            //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
            ApplicationContext applicationContext= new FileSystemXmlApplicationContext("D:\\IDEA\\SSM\\Spring\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");
    
            //2.根据id获取bean对象
            IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
            IAccountDao accountDao = applicationContext.getBean("accountDao",IAccountDao.class);
    
            System.out.println(accountService);
            System.out.println(accountDao);
    
        }
    
    }
    
    
  2. 在模拟表现层中Client.java进行ApplicationContext接口的演练

    //模拟一个表现层,用于调用业务层
    public class Client {
    
        /**
         * 获取spring的IOC核心容器,并根据id获取对象
         *
         * ApplicationContext的三个常用实现类:
         *      ClassPathXmlApplicationContext: 他可以加载类路径下的配置文件,要求配置文件必须在类路径下, 不在的话,加载不了
         *      FileSystemXmlApplicationContext: 他可以加载磁盘任意路径下的配置文件(必须有访问权限)
         *      AnnotationConfigApplicationContext: 它适用于读取注解创建容器的(是明天的内容)
         *
         * 核心容器的两个接口引发的问题:
         *      ApplicationContext:             单例对象适用      更多采用此接口
         *          他在构建核心容器时, 创建对象采取的策略是采用立即加载的方式,也就额是说,只要一读取配置文件法伤就创建配置文件中配置的对象
         *      BeanFactory:                    多例对象适用
         *          他在构建核心容器时,创建对象采取的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象
         * @param args
         */
    
        public static void main(String[] args) {
            //1.获取核心容器对象
            //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    //        ApplicationContext applicationContext= new FileSystemXmlApplicationContext("D:\\IDEA\\SSM\\Spring\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");
    //
    //        //2.根据id获取bean对象
    //        IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
    //        IAccountDao accountDao = applicationContext.getBean("accountDao",IAccountDao.class);
    //
    //        System.out.println(accountService);
    //        System.out.println(accountDao);
    
            //BeanFactory演练:
            Resource resource = new ClassPathResource("bean.xml");
            BeanFactory factory = new XmlBeanFactory(resource);
    
            IAccountService accountService = factory.getBean("accountService",IAccountService.class);
            System.out.println(accountService);
        }
    }
    

说明:运行时可以采用断点调试

3.6 Spring中bean的细节

3.6.1 创建bean的三种方法
  1. 创建项目 day01_eesy_04bean

  2. 将项目 day01_eesy_03spring 下的src/main目录下的文件都复制到 项目day01_eesy_04bean目录下

  3. 分析创建bean的三种方法

    1. 使用默认构造函数创建

      在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

    2. 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)

    3. 使用某个类中的静态方法创建对象,并存入Spring容器

  4. 第一种方法案例:

    在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来管理-->
    
        <!--Spring对bean的管理细节
            1.创建bean的三种方式
            2.bean对象的作用范围
            3.bean对象的生命周期
            -->
    
        <!--创建Bean的三种方式-->
        <!--  第一种方式:使用默认构造函数创建,
                在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,
                采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
                -->
      <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"</bean>
    </beans>
    
  5. 第二种方法案例

    • 创建工厂类InstanceFactory.java

      package com.itheima.factory;
      
      import com.itheima.service.IAccountService;
      import com.itheima.service.impl.AccountServiceImpl;
      
      //模拟一个工厂类(该类可能是存在于jar包中的,不能通过修改源码增加默认构造函数)
      public class InstanceFactory {
      
          public IAccountService getAccountService(){
              return new AccountServiceImpl();
          }
      }
      
    • 在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来管理-->
      
          <!--Spring对bean的管理细节
              1.创建bean的三种方式
              2.bean对象的作用范围
              3.bean对象的生命周期
              -->
      
          <!--创建Bean的三种方式-->
          <!--  第一种方式:使用默认构造函数创建,
                  在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,
                  采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
                  -->
          <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>-->
      
      
          <!--第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)-->
         <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
          <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
      
      </beans>
      
      
  6. 第三种方法案例

    • 创建工厂类StaticFactory.java

      //模拟一个工厂类(该类可能是存在于jar包中的,不能通过修改源码增加默认构造函数)
      public class StaticFactory {
      
          public static IAccountService getAccountService(){
              return new AccountServiceImpl();
          }
      
    • 在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来管理-->
      
          <!--Spring对bean的管理细节
              1.创建bean的三种方式
              2.bean对象的作用范围
              3.bean对象的生命周期
              -->
      
          <!--创建Bean的三种方式-->
          <!--  第一种方式:使用默认构造函数创建,
                  在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,
                  采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
                  -->
          <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>-->
      
      
          <!--第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)-->
          <!--<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>-->
          <!--<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->
      
      
          <!--第三种方法:使用某个类中的静态方法创建对象,并存入Spring容器-->
          <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>
      
      </beans>
      
      
3.6.2 bean对象的作用范围
<!--bean的作用范围调整
    bean标签的scope属性:
        作用: 用于指定bean的作用范围
        取值:     常用的是 singleton 和 prototype
            singleton: 单例(默认值)
            prototype: 多例的
            request: 作用于web应用的请求范围
            session: 作用于web应用的会话范围
            global-session: 作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session
-->

多例案例:在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来管理-->

    <!--Spring对bean的管理细节
        1.创建bean的三种方式
        2.bean对象的作用范围
        3.bean对象的生命周期
        -->

    <!--创建Bean的三种方式-->
    <!--  第一种方式:使用默认构造函数创建,
            在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,
            采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
            -->
    <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>-->


    <!--第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)-->
    <!--<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>-->
    <!--<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->


    <!--第三种方法:使用某个类中的静态方法创建对象,并存入Spring容器-->
    <!--<bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>-->

    <!--bean的作用范围调整
        bean标签的scope属性:
            作用: 用于指定bean的作用范围
            取值:     常用的是 singleton 和 prototype
                singleton: 单例(默认值)
                prototype: 多例的
                request: 作用于web应用的请求范围
                session: 作用于web应用的会话范围
                global-session: 作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session
    -->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"></bean>


</beans>

Client.java类

//模拟一个表现层,用于调用业务层
public class Client {


    public static void main(String[] args) {
        //1.获取核心容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        //ApplicationContext applicationContext= new FileSystemXmlApplicationContext("D:\\IDEA\\SSM\\Spring\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");

        //2.根据id获取bean对象
        IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
        IAccountService accountService2 = (IAccountService) applicationContext.getBean("accountService");

        System.out.println(accountService == accountService2);
      //  accountService.saveAccount();


    }

}

运行结果:

在这里插入图片描述

3.6.3 bean对象的生命周期

单例对象:
出生: 容器创建时对象出生
活着: 只要容器还在, 对象就一直活着
死亡: 容器销毁, 对象消亡
总结:单例对象的生命周期和容器相同
多例对象:
出生: 当我们使用对象时spring框架为我们创建
活着: 对象只要在使用过程中就一直活着
死亡: 当对象长时间不用,且没有别的对象引用时, 由Java的垃圾回收器回收

案例:

  • 在AccountServiceImpl.java文件中添加初始化方法

    //账户的业务层实现类
    public class AccountServiceImpl implements IAccountService {
    
    
    
        public AccountServiceImpl(){
            System.out.println("对象AccountDaoImpl创建了");
        }
    
        public void saveAccount() {
            System.out.println("saveAccount方法执行了");
        }
    
        public void init() {
            System.out.println("对象初始化了");
        }
    
        public void destroy() {
            System.out.println("对象销毁了");
        }
    }
    
  • 在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来管理-->
    
        <!--Spring对bean的管理细节
            1.创建bean的三种方式
            2.bean对象的作用范围
            3.bean对象的生命周期
            -->
    
        <!--创建Bean的三种方式-->
        <!--  第一种方式:使用默认构造函数创建,
                在spring的配置文件中使用bean标签,配以id和class属性以后,且没有其他属性和标签时,
                采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
                -->
        <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>-->
    
    
        <!--第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)-->
        <!--<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>-->
        <!--<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->
    
    
        <!--第三种方法:使用某个类中的静态方法创建对象,并存入Spring容器-->
        <!--<bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>-->
    
        <!--bean的作用范围调整
            bean标签的scope属性:
                作用: 用于指定bean的作用范围
                取值:     常用的是 singleton 和 prototype
                    singleton: 单例(默认值)
                    prototype: 多例的
                    request: 作用于web应用的请求范围
                    session: 作用于web应用的会话范围
                    global-session: 作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session
        -->
        <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"></bean>-->
    
        <!--bean对象的生命周期
                单例对象:
                    出生: 容器创建时对象出生
                    活着: 只要容器还在, 对象就一直活着
                    死亡: 容器销毁, 对象消亡
                    总结:单例对象的生命周期和容器相同
                多例对象:
                    出生: 当我们使用对象时spring框架为我们创建
                    活着: 对象只要在使用过程中就一直活着
                    死亡: 当对象长时间不用,且没有别的对象引用时, 由Java的垃圾回收器回收
           -->
        <!--<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="singleton"-->
              <!--init-method="init" destroy-method="destroy"></bean>-->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"
                init-method="init" destroy-method="destroy"></bean>
    </beans>
    
  • 在表现层Client.java类中运行

    //模拟一个表现层,用于调用业务层
    public class Client {
    
    
        public static void main(String[] args) {
            //1.获取核心容器对象
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
            //ApplicationContext applicationContext= new FileSystemXmlApplicationContext("D:\\IDEA\\SSM\\Spring\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");
    
            //2.根据id获取bean对象
            IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
    
            accountService.saveAccount();
    
            //手动关闭容器
            ((ClassPathXmlApplicationContext) applicationContext).close();
        }
    }
    
  • 运行结果

    • 单例模式:

在这里插入图片描述

  • 多例模式:

在这里插入图片描述

3.7 Spring的依赖注入

Spring中的依赖注入:

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

准备工作:

1. 创建项目 day01_eesy_05DI
  1. 进行 pom.xml的相关配置, 导入Spring框架所需要的jar包

  2. 将项目 day01_eesy_04bean 中 src/main 目录下的文件复制到 day01_eesy_05DI 的 src/main目录下

  3. 将 factory相关文件及 AccountServiceImpl.java 的 init 和 destroy 方法删除

  4. 目录结构

在这里插入图片描述

3.7.1 构造函数注入
  1. 构造函数注入介绍

    构造函数注入
    使用的标签: constructor-arg
    标签出现的位置: bean标签的内部
    标签的属性:
    type: 用于指定要注入的数据的数据类型, 该数据类型也是构造函数中某个或某些参数的类型
    index: 用于指定要注入的数据 给构造函数中指定索引位置的参数赋值,索引的位置是从0开始
    name: 用于指定给构造函数中指定名称的参数赋值 常用
    ==以上三个用于指定给构造函数中哪个参数赋值=
    value: 用于提供基本类型和String类型的数据
    ref: 用于指定其他的bean类型数据; 他只得就是在Spring的IOC核心容器中出现过的bean对象
    优势:

    ​ 在获取bean对象是,注入数据是必须的操作,否则对象无法创建成功

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

  2. 案例

    1. 修改业务层 AccountServiceImpl.java 的构造函数, 以及saveAccount 方法,添加成员变量

      //账户的业务层实现类
      public class AccountServiceImpl implements IAccountService {
      
          //说明: 如果是经常变化的数据, 并不适用于注入的方式
      
          private String name;
      
          private Integer age;
      
          private Date birthday;
      
          public AccountServiceImpl(String name, Integer age, Date birthday){
              this.name = name;
              this.age = age;
              this.birthday = birthday;
      
          }
      
          public void saveAccount() {
              System.out.println("saveAccount方法执行了"+ name +age +birthday);
          }
      
      }
      
    2. 在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中的依赖注入:
                  依赖注入:
                      Dependency Injection
                  IOC的作用:
                      降低程序间的依赖耦合(依赖关系)
                  依赖关系的管理:
                      以后都交给Spring来维护
                  在当前类需要用到其它类的对象的时候, 由Spring为我们提供, 我们只需要在配置文件中说明
                  依赖关系的维护, 就称之为依赖注入
                  依赖注入:
                      能注入的数据 有三类:
                          基本类型和String
                          其他bean类型(在配置文件中或者注解配置过的bean)
                          复杂类型/集合类型
                      注入的方式   有三种:
                          第一种: 使用构造函数提供
                          第二种: 使用set方法提供
                          第三种: 使用注解提供(明天的内容)
          -->
      
          <!--
              构造函数注入
              使用的标签: constructor-arg
              标签出现的位置: bean标签的内部
              标签的属性:
                  type: 用于指定要注入的数据的数据类型, 该数据类型也是构造函数中某个或某些参数的类型
                  index: 用于指定要注入的数据 给构造函数中指定索引位置的参数赋值,索引的位置是从0开始
                  name: 用于指定给构造函数中指定名称的参数赋值           常用
                  ================以上三个用于指定给构造函数中哪个参数赋值===========================
                  value: 用于提供基本类型和String类型的数据
                  ref:   用于指定其他的bean类型数据; 他只得就是在Spring的IOC核心容器中出现过的bean对象
      
                  优势:
                      在获取bean对象是,注入数据是必须的操作,否则对象无法创建成功
                  弊端:
                      改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供
      
      
            -->
          <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
              <constructor-arg name="name" value="text"></constructor-arg>
              <constructor-arg name="age"  value="18"></constructor-arg>
              <constructor-arg name="birthday" ref="now"></constructor-arg>
          </bean>
      
          <bean id="now" class="java.util.Date"></bean>
      
      
      </beans>
      
      
    3. 在模拟表现层中进行运行

      //模拟一个表现层,用于调用业务层
      public class Client {
          
          public static void main(String[] args) {
              //1.获取核心容器对象
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
              //2.根据id获取bean对象
              IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
              accountService.saveAccount();
           
          }
      
      }
      
      
    4. 运行结果

在这里插入图片描述

3.7.2 set方法注入
  1. set方法注入介绍

    set方法注入:
    涉及的标签: property
    出现的位置: bean标签的内部
    标签的属性:
    name: 用于指定注入时所调用的set方法名称
    value: 用于提供基本类型和String类型的数据
    ref: 用于指定其他的bean类型数据; 他指的就是在Spring的IOC核心容器中出现过的bean对象

  2. 案例

    1. 创建业务层 AccountServiceImpl2.java

      //账户的业务层实现类
      public class AccountServiceImpl2 implements IAccountService {
      
          //说明: 如果是经常变化的数据, 并不适用于注入的方式
      
          private String name;
      
          private Integer age;
      
          private Date birthday;
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          public void saveAccount() {
              System.out.println("saveAccount方法执行了 "+ name+" " +age+" " +birthday);
          }
      
      }
      
      
    2. 在配置文件 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中的依赖注入:
                  依赖注入:
                      Dependency Injection
                  IOC的作用:
                      降低程序间的依赖耦合(依赖关系)
                  依赖关系的管理:
                      以后都交给Spring来维护
                  在当前类需要用到其它类的对象的时候, 由Spring为我们提供, 我们只需要在配置文件中说明
                  依赖关系的维护, 就称之为依赖注入
                  依赖注入:
                      能注入的数据 有三类:
                          基本类型和String
                          其他bean类型(在配置文件中或者注解配置过的bean)
                          复杂类型/集合类型
                      注入的方式   有三种:
                          第一种: 使用构造函数提供
                          第二种: 使用set方法提供
                          第三种: 使用注解提供(明天的内容)
          -->
      
          <!--
              构造函数注入
              使用的标签: constructor-arg
              标签出现的位置: bean标签的内部
              标签的属性:
                  type: 用于指定要注入的数据的数据类型, 该数据类型也是构造函数中某个或某些参数的类型
                  index: 用于指定要注入的数据 给构造函数中指定索引位置的参数赋值,索引的位置是从0开始
                  name: 用于指定给构造函数中指定名称的参数赋值           常用
                  ================以上三个用于指定给构造函数中哪个参数赋值===========================
                  value: 用于提供基本类型和String类型的数据
                  ref:   用于指定其他的bean类型数据; 他只得就是在Spring的IOC核心容器中出现过的bean对象
      
                  优势:
                      在获取bean对象是,注入数据是必须的操作,否则对象无法创建成功
                  弊端:
                      改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供
      
      
            -->
          <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
              <constructor-arg name="name" value="text"></constructor-arg>
              <constructor-arg name="age"  value="18"></constructor-arg>
              <constructor-arg name="birthday" ref="now"></constructor-arg>
          </bean>
          <!--配置一个日期对象-->
          <bean id="now" class="java.util.Date"></bean>
      
      
          <!--
              set方法注入:
                  涉及的标签: property
                  出现的位置: bean标签的内部
                  标签的属性:
                      name: 用于指定注入时所调用的set方法名称
                      value: 用于提供基本类型和String类型的数据
                      ref: 用于指定其他的bean类型数据; 他指的就是在Spring的IOC核心容器中出现过的bean对象
             -->
          <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
              <property name="name" value="Test"></property>
              <property name="age" value="18"></property>
              <property name="birthday" ref="now"></property>
          </bean>
      
      
    3. 在模拟表现Client.java中运行

      //模拟一个表现层,用于调用业务层
      public class Client {
      
          public static void main(String[] args) {
              //1.获取核心容器对象
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
              //2.根据id获取bean对象
      //        IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
      //        accountService.saveAccount();
      
              IAccountService accountService = (IAccountService) applicationContext.getBean("accountService2");
              accountService.saveAccount();
      
          }
      
      }
      
    4. 运行结果

在这里插入图片描述

3.7.3 注入集合数据
  1. 集合数据注入介绍

    复杂类型的注入/集合类型的注入

    • 用于给List结构集合注入的标签有:
      list array set
    • 用于给Map结构集合注入的标签有:
      map props
      结构相同, 标签可以互换
  2. 案例

    1. 创建业务实现类AccountServiceImpl3.java

      //账户的业务层实现类
      public class AccountServiceImpl3 implements IAccountService {
      
      
          private String[] myStrs;
      
          private List<String> myList;
      
          private Set<String> mySet;
      
          private Map<String,String> myMap;
      
          private Properties myProps;
      
          public void setMyStrs(String[] myStrs) {
              this.myStrs = myStrs;
          }
      
          public void setMyList(List<String> myList) {
              this.myList = myList;
          }
      
          public void setMySet(Set<String> mySet) {
              this.mySet = mySet;
          }
      
          public void setMyMap(Map<String, String> myMap) {
              this.myMap = myMap;
          }
      
          public void setMyProps(Properties myProps) {
              this.myProps = myProps;
          }
      
          public void saveAccount() {
              System.out.println(Arrays.toString(myStrs));
              System.out.println(myList);
              System.out.println(mySet);
              System.out.println(myMap);
              System.out.println(myProps);
          }
      }
      
      1. 在配置文件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中的依赖注入:
                    依赖注入:
                        Dependency Injection
                    IOC的作用:
                        降低程序间的依赖耦合(依赖关系)
                    依赖关系的管理:
                        以后都交给Spring来维护
                    在当前类需要用到其它类的对象的时候, 由Spring为我们提供, 我们只需要在配置文件中说明
                    依赖关系的维护, 就称之为依赖注入
                    依赖注入:
                        能注入的数据 有三类:
                            基本类型和String
                            其他bean类型(在配置文件中或者注解配置过的bean)
                            复杂类型/集合类型
                        注入的方式   有三种:
                            第一种: 使用构造函数提供
                            第二种: 使用set方法提供
                            第三种: 使用注解提供(明天的内容)
            -->
        
            <!--
                构造函数注入
                使用的标签: constructor-arg
                标签出现的位置: bean标签的内部
                标签的属性:
                    type: 用于指定要注入的数据的数据类型, 该数据类型也是构造函数中某个或某些参数的类型
                    index: 用于指定要注入的数据 给构造函数中指定索引位置的参数赋值,索引的位置是从0开始
                    name: 用于指定给构造函数中指定名称的参数赋值           常用
                    ================以上三个用于指定给构造函数中哪个参数赋值===========================
                    value: 用于提供基本类型和String类型的数据
                    ref:   用于指定其他的bean类型数据; 他只得就是在Spring的IOC核心容器中出现过的bean对象
        
                    优势:
                        在获取bean对象是,注入数据是必须的操作,否则对象无法创建成功
                    弊端:
                        改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供
        
        
              -->
            <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
                <constructor-arg name="name" value="text"></constructor-arg>
                <constructor-arg name="age"  value="18"></constructor-arg>
                <constructor-arg name="birthday" ref="now"></constructor-arg>
            </bean>
            <!--配置一个日期对象-->
            <bean id="now" class="java.util.Date"></bean>
        
        
            <!--
                set方法注入:                更常用的方式
                    涉及的标签: property
                    出现的位置: bean标签的内部
                    标签的属性:
                        name: 用于指定注入时所调用的set方法名称
                        value: 用于提供基本类型和String类型的数据
                        ref: 用于指定其他的bean类型数据; 他指的就是在Spring的IOC核心容器中出现过的bean对象
        
                    优势:
                        创建对象时没有明确的限制,可以直接使用默认构造函数
                    弊端:
                        如果有某个成员必须有值, 则获取对象时有可能set方法没有执行
               -->
            <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
                <property name="name" value="Test"></property>
                <property name="age" value="18"></property>
                <property name="birthday" ref="now"></property>
            </bean>
        
        
            <!--
                复杂类型的注入/集合类型的注入
                用于给List结构集合注入的标签有:
                    list array set
                用于给Map结构集合注入的标签有:
                    map props
                结构相同, 标签可以互换
              -->
            <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3">
                <property name="myStrs">
                    <array>
                        <value>aaa</value>
                        <value>bbb</value>
                        <value>ccc</value>
                    </array>
                </property>
        
                <property name="myList">
                    <list>
                        <value>aaa</value>
                        <value>bbb</value>
                        <value>ccc</value>
                    </list>
                </property>
        
                <property name="mySet">
                    <set>
                        <value>aaa</value>
                        <value>bbb</value>
                        <value>ccc</value>
                    </set>
                </property>
        
                <property name="myMap">
                    <map>
                        <entry key="testA" value="aaa"></entry>
                        <entry key="testB">
                            <value>bbb</value>
                        </entry>
                    </map>
                </property>
        
                <property name="myProps">
                    <props>
                        <prop key="teatA">aaa</prop>
                        <prop key="testB">bbb</prop>
                    </props>
                </property>
            </bean>
        
        </beans>
        
        
      2. 在模拟表现层Client.java中运行

        //模拟一个表现层,用于调用业务层
        public class Client {
        
            public static void main(String[] args) {
                //1.获取核心容器对象
                ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
                //2.根据id获取bean对象
        //        IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
        //        accountService.saveAccount();
        
        //        IAccountService accountService = (IAccountService) applicationContext.getBean("accountService2");
        //        accountService.saveAccount();
        
                IAccountService accountService = (IAccountService) applicationContext.getBean("accountService3");
                accountService.saveAccount();
        
        
            }
        
        }
        
      3. 运行结果

      在这里插入图片描述

      1. 目录结构

    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值