ioc(控制反转),di(依赖注入)

本文深入探讨了IoC(控制反转)与DI(依赖注入)的概念及其在Java开发中的应用。解释了这两种设计思想如何帮助提升组件重用率,搭建灵活可扩展的平台。并详细说明了Spring框架如何通过反射实现依赖注入。

  Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

 DI—Dependency Injection,即“依赖注入”组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。

在java中

对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的

在系统运行时,spring会在适当的时候制造一个对象,然后像打针一样,注射到A当中

那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

 从注入方法上看,主要可以划分为三种类型:构造函数注入、属性注入和接口注入。Spring支持构造函数注入和属性注入。

 IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

 

  • 控制反转(IoC/Inverse Of Control):   调用者不再创建被调用者的实例,由autofac框架实现(容器创建)所以称为控制反转。
  • 依赖注入(DI/Dependence injection) :   容器创建好实例后再注入调用者称为依赖注入。

 

### 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自动完成就好。特别是当涉及到大量第三方库集成的情况下,这种方法的优势尤为明显。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值