一、概念:
**控制反转(Inversion of Control,英文缩写为IoC)****:****是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。
2020整理收集的一线互联网公司面试真题(都整理成文档),有很多干货,包含netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,我感觉在面试这块讲的非常清楚:获取面试资料只需:点击这里领取!!!暗号:CSDN
控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)(依赖注入应用比较广泛)
依赖注入:组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造子注入(Constructor Injection)
二、区别:
控制反转:创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是你在xml文件控制,侧重于原理。
依赖注入:创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
**依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;
**
控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
三、依赖注入机制的过程
待注入的业务对象:
Content.java
public class MyBusiness {
private Content myContent;
public MyBusiness(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
}
MyBusniess类展示了一个业务组件,它的实现需要对象Content的注入。
代码3,代码4,代码5,6分别演示构造子注入(Constructor Injection),设值注入(Setter Injection)和接口注入(Interface Injection)三种方式。
代码3
1.构造子注入(Constructor Injection)
MyBusiness.java
public class MyBusiness {
private Content myContent;
public MyBusiness(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
代码4
2.设值注入(Setter Injection)
MyBusiness.java
public interface InContent {
void createContent(Content content);
}
代码5
设置注入接口
InContent.java
public interface InContent {
void createContent(Content content);
}
代码6
3.接口注入(Interface Injection)
MyBusiness.java
public class MyBusiness implements InContent{
private Content myContent;
public void createContent(Content content)
{
myContent = content;
}
public void doBusniess()
{
myContent.BusniessContent();
}
public void doAnotherBusniess(){
myContent.AnotherBusniessContent();
}
}
四、依赖查找的过程
下面代码展示了基于JNDI实现的依赖查找机制:
public class MyBusniessObject{
private DataSource ds;
private MyCollaborator myCollaborator;
public MyBusnissObject()
{
Context ctx = null;
try
{
ctx = new InitialContext();
ds = (DataSource) ctx.lookup(“java:comp/env/dataSourceName”);
myCollaborator = (MyCollaborator)ctx.lookup(“java:comp/env/myCollaboratorName”);
}……
依赖查找的主要问题是,这段代码必须依赖于JNDI环境,所以它不能在应用服务器之外运行,并且如果要用别的方式取代JNDI来查找资源和协作对象,就必须把JNDI代码抽出来重构到一个策略方法中去。
总结:
其实IoC/DI对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。
应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC/DI容器来创建并注入它所需要的资源了。
这么小小的一个改变其实是编程思想的一个大进步,这样就有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。