控制反转(Inversion of Control)和依赖注入(Dependency Injection):
IoC,直观地讲,就是容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。 
依赖注入是指所依赖的对象不是由自己new出来的,而是用别的方式注入的.Spring的依赖注入是在BeanFactory创建bean的时候完成的.通常是在"bean"类中定义了"依赖"(成员变量,type为别的类,最好是interface或者abstract class),BeanFactory通过配置注入这些"依赖"(BeanFactory创建bean的时候赋值给这些成员变量).当这些"依赖"的实现发生变化的时候,不需要修改"bean"类,而只需要修改Spring的配置文件.或者通过配置新的"依赖"实现,实现新的业务而不用修改"bean"类.
通常,在JAVA中为了完成某一个业务的处理,通常要一个流程控制的类调用其它很多辅助的类来完成。传统的编程均要使用像new object()这样的语法来完成要使用的辅助类然后再调用辅助类来完成一个流程中某一个工作。如果因为业务变化,这个辅助类要换成另一个类,就必须在控制流程的类中new()另一个类,对象间的耦合度很高。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关心业务流程逻辑本身就可以了。从这方面来说,对象如何得到他的辅助类对象的责任被反转(IoC)。

比如有一个业务:对输入数据处理,返回结果,现有的类如下:

ProcessBea:Spring的bean类.

public class ProcessBean {
    private Processor processor;
   
    public Processor getProcessor() {
        return processor;
    }

    public void setProcessor(Processor processor) {
        this.processor = processor;
    }

    public Result process(InputData data) {
       
        return processor.process(data);
    }
}
bean类的依赖:
public interface Processor {
    public Result process(InputData data);
}

public class InputData {
    private String businessType;
    private Map inputData = new HashMap();

    public String getBusinessType() {
        return businessType;
    }

    public void setBusinessType(String businessType) {
        this.businessType = businessType;
    }

    public Map getInputData() {
        return inputData;
    }

    public void setInputData(Map inputData) {
        this.inputData = inputData;
    }
   
   
}

public class Result {
    String result;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
   
}
bean类的依赖的实现:
public class ProcessorImplA implements Processor {
    public Result process(InputData data) {
        Result rt = new Result();
       
        // process steps by using input data...
       
        rt.setResult("process result from ProcessorImplA");
       
        return rt;
    }

}
然后在配置文件中对bean进行配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
   "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean name="ProcessorImplA" class="com.test.spring.di.ProcessorImplA"/>
    <bean name="ProcessorImplB" class="com.test.spring.di.ProcessorImplB"/>


    <bean name="businessABean" class="com.test.spring.di.ProcessBean">
        <property name="processor" ref="ProcessorImplA"/>
    </bean>

</beans>
提供给调用者调用的类:
public class ProcessFacade {
   
    private static BeanFactory factory;
    static{
        Resource resource = new ClassPathResource("conf/diAppcontext.xml");
        factory = new XmlBeanFactory(resource);
    }
   
    public static Result testDI(InputData data){
        ProcessBean processBean = (ProcessBean) factory.getBean(data.getBusinessType());
        return processBean.process(data);
       
    }
}
调用者通过如下代码调用:

InputData data = new InputData();
data.setBusinessType("businessABean");
log.info(ProcessFacade.testDI(data).getResult());

当有新的处理业务的是候,通过提供一个新的依赖实现,把不同的依赖注入到bean类里面而支持新的业务.

一个新的依赖实现:

public class ProcessorImplB implements Processor {
    public Result process(InputData data) {
        Result rt = new Result();
       
        // process steps by using input data...
       
        rt.setResult("process result from ProcessorImplB");
       
        return rt;
    }

}
把不同的依赖注入到bean类里面:

<bean name="businessBBean" class="com.test.spring.di.ProcessBean">
        <property name="processor" ref="ProcessorImplB"/>
</bean>

调用者通过如下代码调用新的业务:

InputData data = new InputData();
data.setBusinessType("businessBBean");
log.info(ProcessFacade.testDI(data).getResult());

对如服务提供者(bean类,facade类)来说,不需要修改代码,而是通过注入不同的依赖,提供新的服务.

Spring通过配置bean的property(setter based dependency injection),bean的构造函数的参数或者工厂类的工厂方法的参数来实现注入(constructor based dependency injection).

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐