IOC解析

作者: 若兮缘 | 来源:发表于2019-01-15 22:47 被阅读16次

IOC概述

IOC: 控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护
DI: (Dependency Injection)依赖注入,是其一种实现方式
目的: 创建对象并且组装对象之间的关系

2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地
分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由
IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)。他的这个答案,
实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中

IOC示例

导入jar包:
4个核心(beans、core、context、expression) + 1个依赖(commons-logging-xxx.jar) spring容器核心包
业务类:

public interface OneInterface {
    public void say(String arg);    
}
public class OneInterfaceImpl implements OneInterface {
    public void say(String arg) {
        System.out.println("ServiceImpl say: " + arg);
    }
}

配置文件:

<?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" >
        
    <bean id="oneInterface" class="com.imooc.ioc.interfaces.OneInterfaceImpl"></bean>
 </beans>

测试类

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase {

    public TestOneInterface() {
        super("classpath*:spring-ioc.xml");
    }
    
    @Test
    public void testSay() {
        //OneInterface oneInterface = super.getBean(OneInterface.class);
        //OneInterface oneInterface = super.getBean(OneInterfaceImpl.class);
        OneInterface oneInterface = super.getBean("oneInterface");
        oneInterface.say("This is a test.");
    }
}

结果:ServiceImpl say: This is a test.

DI示例

DI Dependency Injection,依赖注入,依赖:一个对象需要使用另一个对象,
注入:通过setter方法或构造方法进行另一个对象实例设置
业务类:

public interface InjectionDAO { 
    public void save(String arg);
}
public class InjectionDAOImpl implements InjectionDAO {
    public void save(String arg) {
        //模拟数据库保存操作
        System.out.println("保存数据:" + arg);
    }
}
public interface InjectionService { 
    public void save(String arg);
}
public class InjectionServiceImpl implements InjectionService {
    
    private InjectionDAO injectionDAO;  
    //构造器注入
    public InjectionServiceImpl(InjectionDAO injectionDAO1) {
        this.injectionDAO = injectionDAO1;
    }
    
    //设值注入
    public void setInjectionDAO(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }

    public void save(String arg) {
        //模拟业务操作
        System.out.println("Service接收参数:" + arg);
        arg = arg + ":" + this.hashCode();
        injectionDAO.save(arg);
    }   
}

配置文件:

<?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">

    <!-- 设置注入 -->
    <bean id="injectionService1" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
        <property name="injectionDAO" ref="injectionDAO"></property>
    </bean>
    <!-- 构造注入 -->
    <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
        <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
    </bean>

    <bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>

</beans>

测试类:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestInjection extends UnitTestBase {
    
    public TestInjection() {
        super("classpath:spring-injection.xml");
    }
    
    @Test
    public void testSetter() {
        InjectionService service = super.getBean("injectionService1");
        service.save("这是要保存的数据");
    }
    
    @Test
    public void testCons() {
        InjectionService service = super.getBean("injectionService");
        service.save("这是要保存的数据");
    }
    
}

结果:Service接收参数:这是要保存的数据
保存数据:这是要保存的数据:1995616381
1.修改参数名将报错:setInjectionDAO(InjectionDAO injectionDAO1),
修改属性名正常:private InjectionDAO injectionDAO1;
2.去掉带参构造方法构造注入报错,去掉默认构造方法set注入方式报错

Spring配置

bean配置:
语法: <bean id="唯一引用" class="全限定类名"> 配置的bean会在spring容器加载后进行初始化
示例: <bean id="oneInterface" class="com.imooc.ioc.interfaces.OneInterfaceImpl"></bean>
bean获取:
语法: applicationContext.getBean(String name) name即为配置的bean的id
applicationContext.getBean(Class<T> requiredType) 根据类类型获取bean对象
示例: applicationContext.getBean("oneInterface")
applicationContext.getBean(OneInterface.class)

相关文章

网友评论

      本文标题:IOC解析

      本文链接:https://www.haomeiwen.com/subject/epwudqtx.html