IOC课程整理-6 Spring IoC 依赖注入

1 依赖注入的模式和类型

模式

类型

2 自动绑定(Autowiring)

官方定义

"自动装配是Spring框架中一种机制,用于自动解析和满足bean之间的依赖关系。通过自动装配,Spring容器可以根据类型、名称或其他属性来自动连接协作的bean,而无需显式配置依赖关系。这使得开发者可以更加专注于业务逻辑而不必过多关注bean之间的连接与注入。"

优点

自动装配简化了应用程序的配置工作,提高了开发效率和代码的可读性,同时提供了灵活性和扩展性,使得应用程序更易于维护和演化。

3 自动绑定(Autowiring)模式

4自动绑定的不足

虽然自动绑定(Autowiring)在某些情况下可以提供便利,但也有几个原因导致不建议过度使用或完全依赖自动绑定:

自动绑定使得依赖关系变得隐式,缺乏明确的配置。.autowiring不具有精确性,它是一种猜测性的东西,然而Spring非常在乎精确性 ,Autowiring很难在工具方面进行呈现,很难确定你这个autowiring的bean在上下文是否存在 。如果存在多个定义的bean,会报错,系统不知道你需要的是哪个bean这可能导致代码可读性和可维护性下降,特别是在复杂的应用程序中。

动绑定可能导致组件之间的耦合增加,影响模块化开发和重复使用。当组件之间的依赖关系不明确时,重构和替换组件可能变得困难。

5 Setter 方法注入

例如

6 构造器 注入

例如

复制代码
public class UserService {
    private UserDao userDao;
    
    // 构造器
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
    
    // 其他业务方法...

6 字段注入

7 方法注入

8 接口回调注入

8 依赖注入类型选择

9 限定注入

10 延迟依赖注入

通常的 @Autowired 会及时依赖相关的 Spring Bean,不过此时 Bean 的状态并未完全准备好,所以 ObjectProvider 可以在需要时获取 Spring Bean,更好的状态准备,达到延迟的获取效果。

11 依赖注入的过程和规则

在 AbstractApplicationContext#refresh#finishBeanFactoryInitialization 方法中,初始化所有还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式) 通过 DefaultListableBeanFactory#preInstantiateSingletons 方法进行初始化,会通过 AbstractBeanFactory#getBean(beanName) 方法对每个 Bean 进行初始化 Bean 初始化的过程比较繁琐,大致过程如下:

  1. 先找到对应的 BeanDefinition 对象,然后会走到 AbstractAutowireCapableBeanFactory#createBean 方法,**进行实例化**、**填充属性值**、调用 Bean 的**初始化方法**

  2. 在填充属性值的过程,默认根据类型进行注入,那么在 AbstractAutowireCapableBeanFactory#autowireByType 的方法中会调用 DefaultListableBeanFactory#resolveDependency 方法进行注入,最后还是会通过 AbstractBeanFactory#getBean(beanName) 方法获取到需要注入的 Bean 对象

  3. 在填充属性值的时候也会通过 AutowiredAnnotationBeanPostProcessor 注入属性值,该注入增强器会对 @Autowired 或者 @Value 注解标注的属性进行注入,也是通过 DefaultListableBeanFactory#resolveDependency 方法进行注入。具体过程可看 AutowiredAnnotationBeanPostProcessor 的私有内部类 AutowiredFieldElement#inject 方法

12 @Autowired 注入

1.在doCreateBean中会先调用applyMergedBeanDefinitionPostProcessors,后执行populateBean 所以会先调用postProcessMergedBeanDefinition后执行InstantiationAwareBeanPostProcessor的postProcessProperties。(之后就是要创建Bean,创建bean肯定要看看有没有配置什么字段需要注入->findAutowiringMetadata())

2.postProcessProperties中有两个步骤:

(1)findAutowiringMetadata查找注入元数据,没有缓存就创建,具体是上一节内容。最终会返回InjectionMetadata,里面包括待注入的InjectedElement信息(field、method)等等

(2)执行InjectionMetadata的inject方法,具体为AutowiredFieldElement和AutowiredMethodElement的Inject方法

(2.1)AutowiredFieldElement inject具体流程:

(2.1.1)DependencyDescriptor的创建

(2.1.2)调用beanFactory的resolveDependency获取带注入的bean

(2.1.2.1)resolveDependency根据具体类型返回候选bean的集合或primary 的bean

(2.1.3)利用反射设置field

13!!!TODO

面试题

依赖注入有几种方式

构造器注入

Setter 注入

字段注入

方法注入

接口回调注入

相关推荐
间彧18 分钟前
Java线程池详解与实战指南
java
moisture23 分钟前
CUDA常规知识点
后端·面试
用户2986985301425 分钟前
Java 使用 Spire.PDF 将PDF文档转换为Word格式
java·后端
Reboot31 分钟前
使用cloc统计代码行数
后端
neoooo31 分钟前
当域名遇上家里的电脑:一条隧道通向世界
后端
zjjuejin32 分钟前
Maven依赖管理艺术
后端·maven
RoyLin32 分钟前
TypeScript设计模式:复合模式
前端·后端·typescript
渣哥35 分钟前
ConcurrentHashMap 1.7 vs 1.8:分段锁到 CAS+红黑树的演进与性能差异
java
我的小月月35 分钟前
SQLFE:网页版数据库(VUE3+Node.js)
前端·后端
Alan5215939 分钟前
Java 后端实现基于 JWT 的用户认证和权限校验(含代码讲解)
前端·后端