一.SpringIOC大致流程可以总结为 读取解析配置文件 -> 组装bean定义放到Map -> 根据bean定义依次创建对象 -> 把对象都放到map 这四个大步骤
二.Spring有三种生命周期增强器
- BeanFactoryPostProcessor Bean工厂后置处理器,可以对工厂进行增强
- BeanPostProcessor Bean的后置处理器,对Bean的实例化前后,初始化前后进行干预。
- InitalizingBean Bean完全初始化后可以进行一波处理
Spring的后置处理器是Spring最核心的组件,很多骚操作都是基于后置处理器实现的,比如Aop、事务等,为什么加了@Transaction 注解事务会生效,一定是基于后置处理器对我们的对象在某个时机进行了干预。
三.可以自己实现所有后置处理器,打上断点 追踪堆栈进行分析spring后置处理器的执行时机。下面分析IOC容器的初始化流程
下面是根据Bean的周期和各个后置处理器的执行时机画的流程图,可以根据流程图进行debug调试,通过追踪堆栈了解bean的整个生命周期和Spring对bean增强的时机都有那些
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
Person bean = context.getBean(Person.class);
System.out.println(bean);
}
自己实现一些后置处理器 一共六种:
工厂相关的处理器
/**
* BeanFactory的后置处理器 , PriorityOrdered, Ordered
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public MyBeanDefinitionRegistryPostProcessor(){
System.out.println("MyBeanDefinitionRegistryPostProcessor");
}
@Override //紧接着执行
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor....postProcessBeanFactory...");
}
@Override //先执行的
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanDefinitionRegistry...");
//增强bean定义信息的注册中心,比如自己注册组件
}
}
/**
* BeanFactory的后置处理器
*/
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor(){
System.out.println("MyBeanFactoryPostProcessor...");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor....postProcessBeanFactory==>"+beanFactory);
}
}
Bean相关的处理器
/**
* Bean组件的 PostProcessor;
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor(){
System.out.println("MyBeanPostProcessor...");
}
//初始化后
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessAfterInitialization..."+bean+"==>"+beanName);
return bean;
}
//初始化前
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessBeforeInitialization..."+bean+"==>"+beanName);
return bean; // new Object();
}
}
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public MyInstantiationAwareBeanPostProcessor(){
System.out.println("MyInstantiationAwareBeanPostProcessor...");
} //初始化之前进行后置处理,Spring留给我们给这个组件创建对象的回调。
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessBeforeInstantiation=>"+beanClass+"--"+beanName); //if(class.isAssFrom(Cat.class)){return new Dog()}
return null; //如果我们自己创建了对象返回。Spring则不会帮我们创建对象,用我们自己创建的对象? 我们创建的这个对象,Spring会保存单实例?还是每次getBean都调到我们这里创建一个新的?
}
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessAfterInstantiation=>"+bean+"--"+beanName); //提前改变一些Spring不管的bean里面的属性
return true; //返回false则bean的赋值全部结束
} //解析自定义注解进行属性值注入;pvs 封装了所有的属性信息。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException { //@GuiguValue();redis
System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessProperties=>"+bean+"--"+beanName);
return null;
}
}
@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
public MyMergedBeanDefinitionPostProcessor(){
System.out.println("MyMergedBeanDefinitionPostProcessor...");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessBeforeInitialization...=>"+bean+"--"+beanName);
return bean; //null
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessAfterInitialization..=>"+bean+"--"+beanName);
return null;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessMergedBeanDefinition..=>"+beanName+"--"+beanType+"---"+beanDefinition);
}
@Override
public void resetBeanDefinition(String beanName) {
System.out.println("MyMergedBeanDefinitionPostProcessor...resetBeanDefinition.."+beanName);
}
}
@Component //bean进行代理增强期间进行使用
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
public MySmartInstantiationAwareBeanPostProcessor(){
System.out.println("MySmartInstantiationAwareBeanPostProcessor...");
}
//预测bean的类型,最后一次改变组件类型。
public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor...predictBeanType=>"+beanClass+"--"+beanName);
return null;
}
//返回我们要使用的构造器候选列表
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor...determineCandidateConstructors=>"+beanClass+"--"+beanName);
//返回一个我们指定的构造器
return null;
}
//返回早期的bean引用,定义三级缓存中的bean信息
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor...getEarlyBeanReference=>"+bean+"--"+beanName);
return bean; //
}
}
-
通过debug 首先执行的处理器是 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法,然后追踪堆栈看下执行流程是怎样的,
ClassPathXmlApplicationContext构造器中有一个 refresh() 刷新方法,这个方法就是创建容器的方法,Spring中叫刷新容器
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); //刷新容器
}
}
2.容器刷新分为12大步,创建完ConfigurableListableBeanFactory工厂后,调用了invokeBeanFactoryPostProcessors(xx)对工厂进行增强,我们实现的工厂后置处理器就在这里面执行了
@Override //容器刷新的十二大步。模板模式
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//准备上下文环境 Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//给容器中注册了环境信息作为单实例Bean方便后续自动装配;放了一些后置处理器处理(监听、xxAware功能) Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//留给子类的模板方法,允许子类继续对工厂执行一些处理; Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//【大核心】工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//【核心】注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
//初始化国际化功能 Initialize message source for this context.
initMessageSource();
//初始化事件多播功能(事件派发) Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
//注册监听器,从容器中获取所有的ApplicationListener; Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//【大核心】bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了)
finishBeanFactoryInitialization(beanFactory);
//发布事件 Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
进入invokeBeanFactoryPostProcessors 方法
PostProcessorRegistrationDelegate用来统一处理所有后置处理器,是门面模式的应用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); //执行所有的工厂增强器
//上面的类叫:后置处理器的注册代理(门面模式-装饰模式)
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
进入 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法
(1)第一个循环先执行底层默认的工厂后置处理器,把postProcessBeanDefinitionRegistry方法挨个执行一遍
(2)然后获取所有实现了BeanDefinitionRegistryPostProcessor接口的bean名字 挨个判断哪个实现了PriorityOrdered优先级排序接口的对象,放到currentRegistryProcessors当前处理器集合中,然后调用invokeBeanDefinitionRegistryPostProcessors 方法循环执行postProcessBeanDefinitionRegistry方法
(3)然后判断实现Ordered接口的对象,继续第二步中的遍历执行操作,如果PriorityOrdered 和 Ordered都实现了 以 PriorityOrdered为准
(4)如果俩排序接口都没实现,那么就会走到下边while循环中,先获取所有对象,再排序然后调用invokeBeanDefinitionRegistryPostProcessors方法循环执行postProcessBeanDefinitionRegistry(),然后invokeBeanFactoryPostProcessors执行所有postProcessBeanFactory的回调
至此我们的第一个工厂后置处理器BeanDefinitionRegistryPostProcessor执行完了
(5)倒数第二行invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 里边循环执行了所有实现了BeanFactoryPostProcessor 接口对象的postProcessBeanFactory 方法