Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

时间:2022-05-11 22:29:35

IoC的概念

控制反转(Inversion of Control)英文缩写IoC, 即就是把创建对象的权利交给框架,是框架的重要特征。

包括:依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)

作用:降低程序间的耦合关系

IoC前戏(会用)

准备Spring的开发包,本次使用的是spring5.0.2,要求jdk8版本,tomcat版本8.5以上

spring的官网:http://spring.io/

下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/

下载spring-framework-5.0.2.RELEASE-dist.zip包,解压后得到三个目录。

Spring的目录结构:

docs:API和开发规范

libs:jar包和源码

scheme:约束
Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

首先看一下我们第一个Spring案例的Demo项目结构

    ![](https://img2018.cnblogs.com/blog/1415026/201907/1415026-20190725104610209-1755100781.png)
  1. 创建Maven工程,默认即可,然后在pom.xml里添加下面代码,导入Spring框架的依赖包。

    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    </dependencies>
  2. 在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="accountService" class="com.ben.service.impl.AccountServiceImpl"></bean>
    
        <bean id="accountDao" class="com.ben.dao.impl.AccountDaoImpl"></bean>
    </beans>

    此时标签bean的属性解释:

    id : 获取核心容器对象时的唯一标志;

    class: 指定要创建的全限定名。

  3. 创建业务层接口和实现类

    /**
     * @ClassName: IAccountService
     * @author: benjamin
     * @version: 1.0
     * @description: 账户业务层接口
     * @createTime: 2019/07/21/10:43
     */
    
    public interface IAccountService {
    
        // 模拟保存账户
        void saveAccount();
    }
    
    /**
     * @ClassName: 业务层接口实现类
     * @author: benjamin
     * @version: 1.0
     * @description: TODO
     * @createTime: 2019/07/21/10:45
     */
    
    public class AccountServiceImpl implements IAccountService {
    
        private IAccountDao accountDao; // 此处的依赖关系有待解决
        private AccountServiceImpl(){
            System.out.println("业务层实现类--创建对象");
        }
        public void saveAccount(){
            accountDao.saveAccount();
        }
    }
  4. 创建持久层接口和实现类

    /**
     * @ClassName: IAccountDao
     * @author: benjamin
     * @version: 1.0
     * @description: 账户的持久层接口
     * @createTime: 2019/07/21/10:43
     */
    
    public interface IAccountDao{
        //模拟保存账户
        void saveAccount();
    }
    
    /**
     * @ClassName: AccountDaoImpl
     * @author: benjamin
     * @version: 1.0
     * @description: 账户的持久层实现类
     * @createTime: 2019/07/21/10:44
     */
    
    public class AccountDaoImpl  implements IAccountDao {
        public void saveAccount(){
            System.out.println("持久层实现类--保存账户");
        }
    }
  5. 创建一个表现层,用于调用业务层

    /**
     * @ClassName: Client
     * @author: benjamin
     * @version: 1.0
     * @description: 模拟一个表现层,用于调用业务层
     * @createTime: 2019/07/21/10:43
     */
    
    public class Client {
        // 获取Spring的IoC核心容器,并根据id获取对象
        public static void main(String[] args) {
            //1. 获取核心容器对象
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    //        ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\zhy\\Desktop\\bean.xml");
            //2.根据id获取Bean对象
            // 两种方式:
            IAccountService as = (IAccountService) ac.getBean("accountService");
            IAccountDao adao = ac.getBean("accountDao", IAccountDao.class);
    
            System.out.println(as);
            System.out.println(adao);
    //        as.saveAccount();
        }
    }

    运行结果:
    Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

Spring的工厂类

ApplicationContext接口的3个实现类

Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

  • ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用)
  • FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
  • AnnotationConfigApplicationContext:它是用于读取注解创建容器的

举例:

public static void main(String[] args) {
    //1. 获取核心容器对象,两种方式,推荐第一种
//        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\benjie\\Desktop\\bean.xml");
    //2.根据id获取Bean对象
    // 两种方式:
    IAccountService as = (IAccountService) ac.getBean("accountService");
    IAccountDao adao = ac.getBean("accountDao", IAccountDao.class);

    System.out.println(as);
    System.out.println(adao);
}

ApplicationContext和BeanFactory的区别

ApplicationContext:单例对象适用,采用此接口

它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。

BeanFactory:多例对象使用

它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。

下面我们来用IDEA进行代码调试,

首先我们在程序第27行处打一个断点,点击debug运行。

Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

结果:

Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题

BeanFactory演示,代码如下:

    public static void main(String[] args) {
        //-----BeanFactory----
        Resource resource  = new ClassPathResource("bean.xml");
        BeanFactory factory = new XmlBeanFactory(resource);
        IAccountService as = (IAccountService)factory.getBean("accountService");
        System.out.println(as);
}

发现,只有在使用的时候(打印as)才会创建对象.
Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题