上一篇文章Spring中AOP源码浅析①讲到AOP中实际是通过BeanPostProcesser后置处理器实现的。后置处理器就是在Bean初始化前后进行拦截调用。
那么我们的后置处理器是如何加载和初始化呢?(后置处理器是一类特殊的Bean)
猜想一下,肯定是在普通单例Bean之前进行加载和初始化操作,只有先加载了处理器才能通过处理器去拦截Bean。
那么我们就从业务Bean的加载这一步看源码是如何实现的,实际业务Bean和处理器Bean加载过程类似。还是使用Spring中AOP的使用这篇文章的代码运行调试。(测试类、配置类MainConfig、业务类Fun、切面类LogAspect并且加上相应注解)
第一步Spring容器通过配置类创建Ioc容器:
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
配置类在这篇文章有提到聊一聊SpringBean的生命周期——创建、初始化、销毁。
点进去AnnotationConfigApplicationContext 这个类查看
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
//注册配置类
register(annotatedClasses);
//刷新Spring容器上下文
refresh();
}
处理器和Bean的加载初始化过程就在这个refresh()方法里,点进去
...
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
...
// Register bean processors that intercept bean creation.
//注册拦截Bean创建的后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩余非懒加载单例Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
从源码看拦截的后置处理器的加载是比非懒加载单例Bean要早的。分别是registerBeanPostProcessors(beanFactory),finishBeanFactoryInitialization(beanFactory)这两个方法。
跟进registerBeanPostProcessors(beanFactory)继续看,发现是调用了PostProcessorRegistrationDelegate委托类的registerBeanPostProcessors()方法。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
....
//