什么是依赖注入(IoC)、控制反转(DI) (二)

本文详细解释了依赖注入(DI)和控制反转(IoC)的概念及其应用,通过实例展示了如何减少类之间的耦合度,使得代码更加灵活、易于维护。

IoC 或者 DI 或者 ...一大堆的缩写词
依赖注入和控制反转其实是同一回事,依赖注入最典型的应用就是控制反转

不管是面向对象,还是面向过程,都需要分成许多的块,然后由这些部件协同工作完成任务
要协同工作就会产生依赖,一个方法调用另一个方法,一个对象包含另一个对象
如果对象A包含对象B的话,就需要在A里new一个B
依赖注入从具体类B里抽象出接口IB——IB的具体实现可能有很多B,B1,B2...很多种——这样A可以不用再new具体的B了,而是跟IoC容器说:我要一个IB(getBean("IB"))。然后,由容器根据配置文件来做具体的new的工作。具体new的是哪个,由配置文件从代码外部决定,要更换成B,B1,或是B2...修改配置文件就能做到,不用再改代码了

例:
假设你编写了两个类,一个是人(Person),一个是手机(Mobile)。
人有时候需要用手机打电话,需要用到手机的dialUp方法。
传统的写法是这样:

Java code

public class Person{
public boolean makeCall(long number){
Mobile mobile=new Mobile();
return mobile.dialUp(number);
}
}



也就是说,类Person的makeCall方法对Mobile类具有依赖,必须手动生成一个新的实例new Mobile()才可以进行之后的工作。
依赖注入的思想是这样,当一个类(Person)对另一个类(Mobile)有依赖时,不再该类(Person)内部对依赖的类(Moblile)进行实例化,而是之前配置一个beans.xml,告诉容器所依赖的类(Mobile),在实例化该类(Person)时,容器自动注入一个所依赖的类(Mobile)的实例。
接口:

Java code

public Interface MobileInterface{
public boolean dialUp(long number);
}



Person类:

Java code

public class Person{
private MobileInterface mobileInterface;
public boolean makeCall(long number){
return this.mobileInterface.dialUp(number);
}
public void setMobileInterface(MobileInterface mobileInterface){
this.mobileInterface=mobileInterface;
}
}



在xml文件中配置依赖关系

Java code

<bean id="person" class="Person">
<property name="mobileInterface">
<ref local="mobileInterface"/>
</property>
</bean>
<bean id="mobileInterface" class="Mobile"/>




这样,Person类在实现拨打电话的时候,并不知道Mobile类的存在,它只知道调用一个接口MobileInterface,而MobileInterface的具体实现是通过Mobile类完成,并在使用时由容器自动注入,这样大大降低了不同类间相互依赖的关系。

 

转:http://apps.hi.baidu.com/share/detail/14754545

### IOC控制反转)和DI依赖注入) #### 什么是IoC IoC控制反转,是一种设计模式,其核心在于将原本由程序代码直接操控的对象创建过程交给了专门的容器来处理。这样做的主要目的是为了减少组件之间的耦合度,使得应用程序更加模块化、易于管理和扩展[^1]。 在传统的编程模型中,调用者负责初始化它所需要的资源和服务;而在采用IoC的设计里,则是由外部环境——通常是框架或库,在适当的时候提供这些必要的协作对象给调用方使用[^2]。 #### 什么是DI DI代表依赖注入,这是实现IoC的一种具体方法论。通过这种方式可以更清晰地表达出各个软件单元之间存在的相互依存关系,并且简化了新功能加入时所需修改的工作量。简单来说,就是让某个类不需要自己去寻找它的依赖项而是被动接收它们[^3]。 对于开发者而言,这意味着可以在不改动原有逻辑的前提下轻松替换掉某些特定部分的功能实现,从而提高了系统的灵活性以及便于进行单元测试等活动[^4]。 #### 实现方式 ##### XML配置文件 早期版本中的Spring应用广泛采用了基于XML的方式来进行Bean定义: ```xml <beans> <!-- 定义UserServiceImpl bean --> <bean id="userService" class="com.example.service.UserServiceImpl"> <!-- 设置属性值 --> <property name="userRepository" ref="userRepository"/> </bean> <!-- 定义UserRepositoryImpl bean --> <bean id="userRepository" class="com.example.repository.UserRepositoryImpl"/> </beans> ``` 上述例子展示了如何利用`<bean>`标签声明服务层与数据访问层间的关联关系,其中`ref`关键字用于指示目标引用另一个已注册过的Bean实例。 ##### Java Config 随着Java语言的发展,越来越多的人倾向于使用纯编码的方式来完成同样的事情: ```java @Configuration public class AppConfig { @Bean public UserService userService() { return new UserServiceImpl(userRepository()); } @Bean public UserRepository userRepository(){ return new UserRepositoryImpl(); } } ``` 这段代码片段同样表达了相同的内容,但是是以更为直观的形式呈现出来的。这里借助于`@Configuration`注解标记该类为配置源之一,而内部的方法则分别对应着不同类型的工厂方法,用来生产相应的单例对象供整个上下文共享使用。 ##### 注解驱动 最后一种也是目前最流行的做法便是依靠各种各样的元数据标注来自动生成所需的映射表结构: ```java @Service public class UserServiceImpl implements UserService{ private final UserRepository userRepository; @Autowired public UserServiceImpl(UserRepository userRepository){ this.userRepository = userRepository; } } @Repository public class UserRepositoryImpl implements UserRepository{} ``` 在这个场景下,只要确保所有参与组装操作的角色都已经被正确地标记上了合适的标签即可,剩下的工作交给Spring Boot自动完成就好。特别是当涉及到大量第三方库集成的情况下,这种方法的优势尤为明显。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值