1. 生命周期
总体来说是先refresh() => getBean()
1.1 refresh
- 调用refreshBeanFactory => loadBeanDefinition将会把创建所有的BeanDefinition =》 doScan =》 扫描包中所有注解@Component
- addApplicationContextAwareProcessor => 要在ApplicationContextAwareProcessor中添加ApplicatoinContext本身
- invokeBeanFactoryPostProcessors,调用beanFactoryPostProcessor => PropertyPlaceholderConfigurer(BeanFactoryPostProcessor) 将propertires中的所有属性,注入到BeanDefinition中 诸如此类:${value}
- registerBeanPostProcessors, factory.addBeanPostProcessor
- beanFactory.preInstantiateSingletons() 这里会提前实例化所有的Bean
// 1. 创建 BeanFactory,并加载 BeanDefinition
// loadBeanDefinition 会调用doScan方法,主要是自动扫描包中的所有类,
// 然后把类的信息映射到beanDefinition中
refreshBeanFactory(); => loadBeanDefinition() => doScan()
// 2. 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 3. 添加 ApplicationContextAwareProcessor,让继承自 ApplicationContextAware 的 Bean 对象都能感知所属的 ApplicationContext
// Aware的东西主要发生在getBean()的时候,注入ApplicationContext,而ApplicationContext对象需要在这个上下文获取
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4. 在 Bean 实例化之前,执行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.)
// 这个阶段执行beanFactoryProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 5. BeanPostProcessor 需要提前于其他 Bean 对象实例化之前执行注册操作
registerBeanPostProcessors(beanFactory);
// 6. 初始化事件发布者
initApplicationEventMulticaster();
// 7. 注册事件监听器
registerListeners();
// 8. 提前实例化单例Bean对象
// !!!!!!!!这里会调用所有bean的getBean方法,会预先实例化所有的bean,关于getBean会完成哪些事情,看下面
beanFactory.preInstantiateSingletons();
// 9. 发布容器刷新完成事件
finishRefresh();
1.2 getBean
getBean周期如下:
-
Invoke InstantiationAwareBeanPostProcessor() 在创建类之前运行的PostProcessor(method postProcessBeforeInstantiation)
-
createBeanInstance => cglib或者其他方式调用bean的construct method
-
applyBeanPostProcessorBeforeApplyPropertyValues() 这个步骤会去解析@Value注解,@Autowired注解,@Qualifier注解,主要是为了把beanDefinition中的PropertyValues设置成相应的依赖值
-
applyPropertyValues 将BeanDefinition中的propertyValues设置到bean中
-
调用initializeBean方法。=》5.1 调用injectAwareBean中的set方法,把相应的aware设置到对象中
5.2 applyBeanPostProcessorBeforeInitialization
5.3 调用@Init-method方法
5.4 调用applyBeanPostProcessorAfterInitialization (这个阶段会调用代理对象的创建方法DefaultAdvisorAutoProxyCreator)
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean = null;
try {
bean = resolveBeforeInstantiation(beanName, beanDefinition);
if (bean != null) {
// 这里是不是需要处理一些东西,填充属性
return bean;
}
//create bean
bean = createBeanInstance(beanDefinition, beanName, args);
// 在apply之前把自动注入的属性都加入到properties中
applyBeanPostProcessorsBeforeApplyPropertyValues(beanName, bean, beanDefinition);
//support bean property
applyPropertyValues(beanName, bean, beanDefinition);
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
if (beanDefinition.isSingleton()) {
addSingleton(beanName, bean);
}
return bean;
}
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {
//注入aware对象
injectAwareBean(beanName, bean, beanDefinition);
//前置处理
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
//调用初始化方法
try {
invokeInitMethods(beanName, wrappedBean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
}
//后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
return wrappedBean;
}
2. 三级缓存
Spring三级缓存目的主要为了解决循环依赖的问题。(本身的SingletonBeanRegistry
使用的就是一级缓存)
一级缓存实际上已可解决循环依赖,解决方式如下:
这样做的缺点就是这样会导致,下面这个单例的保存Map里面,会保存着两种类型的副本:
- 调用了构造方法,但未进行属性填充的Bean。(造成这种情况的原因是调用ApplyBeanPropertyValue的过程中跳入到了别的getBean方法)
- 调用了构造方法,也进行了属性填充的Bean。
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
private final Map<String, Object> singleObjects = new ConcurrentHashMap<>();
private final Map<String, DisposableBean> disposableBeans = new ConcurrentHashMap<>();
protected static final Object NULL_OBJECT = new Object();
}
所以,根据单一职责原则,将上面提到的两种bean放到两个不同的map中,
调用了构造方法,但未进行属性填充的Bean,放到二级缓存中
调用了构造方法,也进行了属性填充的Bean,放到一级缓存中。
新的问题:代理对象怎么办?
因为如果遵循上面的解决方案的话,如果这样放的话,代理对象是在postProcessor中代理的,处理之后的bean不会实时的更新到一级缓存中,相当于没有进行了代理。
解决方案:
这种方式即可解决代理对象带来的问题
但是还是那个原则:单一职责原则
所以又增加了一级缓存专门存放代理对象。总的来说,缓存就被划分成了以下几个层次。
- 一级缓存:完全实例化的对象
- 二级缓存:只调用了构造方法的对象。
- 三级缓存:被代理的对象
3. 数据类型转换
这部分主要是围绕三个接口
public interface Converter<S, T> {
T convert(S source);
}
public interface ConverterFactory<S, R>{
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
public interface GenericConverter {
Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, Class sourceType, Class targetType);
}
设计模式
- 工厂方法模式
- 适配器模式