概述
本章节优化上一章节通过构造方法实例化对象属性填充问题的痛点,并解决A bean依赖B bean的问题
整体设计
知识点补充
spring生命周期
在Spring中,Bean的生命周期包括实例化、初始化和销毁三个阶段。下面是对每个阶段的解释:
- 实例化(Instantiation):在这个阶段,Spring容器会根据配置信息或注解创建Bean的实例。实例化可以通过构造函数实现,也可以通过工厂方法或者工厂Bean来实现。
- 初始化(Initialization):在实例化后,Spring会对Bean进行初始化。这个阶段包括以下几个步骤:
a.属性注入:Spring会将配置的属性值或引用注入到Bean的对应属性中。
b.实现Aware接口:如果Bean实现了Aware接口,Spring会调用相应的方法,将容器相关的信息注入到Bean中。
c.自定义初始化方法:如果Bean定义了自定义的初始化方法(通过配置或注解),Spring会在这个阶段调用该方法。 - 销毁(Destruction):当容器关闭或者销毁Bean时,会触发销毁阶段。这个阶段包括以下几个步骤:
a. 实现DisposableBean接口:如果Bean实现了DisposableBean接口,Spring会调用其destroy()方法进行销毁操作。
b. 自定义销毁方法:如果Bean定义了自定义的销毁方法(通过配置或注解),Spring会在这个阶段调用该方法。
类图
时序图
- 初始化 BeanFactory(DefaultListableBeanFactory)
- 注册userDao bean(相关类信息),将注册的类信息放入DefaultListableBeanFactory的map中
- 注册userService bean,将注册的类信息(类对象,属性:依赖B)放入DefaultListableBeanFactory的map中
- 通过bean工厂获取类的对象
调用继承了抽象类AbstractAutowireCapableBeanFactory继承的AbstractBeanFactory的getBean方法
从抽象类AbstractBeanFactory继承的DefaultSingletonBeanRegistry类的getSingleton方法获取类信息 - 存在的话返回
- 不存在的话从AbstractBeanFactory的子类beanFactory(DefaultListableBeanFactory)中获取bean定义
- 从子类BeanFactory(AbstractAutowireCapableBeanFactory)中创建对象
获取Class类信息(传入无参的构造方法)
指定Cglib的子类CglibSubclassingInstantiationStrategy通过cglib实例化并返回Object
将实例化后的对象放到继承的抽象类AbstractBeanFactory继承的DefaultSingletonBeanRegistry类中的map中
返回实例化后的bean - 返回初始化的bean对象,实例化填充属性
/**
* Bean 属性填充
*/
protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) {
try {
PropertyValues propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
if (value instanceof BeanReference) {
// A 依赖 B,获取 B 的实例化
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getBeanName());
}
// 通过反射属性填充
BeanUtil.setFieldValue(bean, name, value);
}
} catch (Exception e) {
throw new BeansException("Error setting property values:" + beanName);
}
}
从beanDefinition中获取属性信息并遍历,对值为BeanReference对象的,去spring容器中获取对象,过程如上述
对获取的属性名和值通过cn.hutool.core.bean的beanUtil进行反射设置
- 继承的抽象类AbstractBeanFactory继承的DefaultSingletonBeanRegistry类中的map将实例化后的对象放入。统一维护bean对象
- 返回bean
小结
A 依赖 B问题:通过继续在DefaultSingletonBeanRegistry中map中获取,不存在的话beanFactory去初始化、实例化该对象并返回给依赖的对象。
问题
A 依赖 B,B 依赖 A这种循环依赖怎么解决?
个人想法:
bean注册的时候,就创建对应的代理Bean,当需要依赖的时候放入代理bean,并去初始化、实例化代理bean