Spring注解--AOP原理(三):BeanPostProcessor创建与注册

1. 用途

Spring 中使用BeanPostProcessor 来拦截bean的创建,并在bean初始化前后,添加相应的操作。

2. 注册流程

  1. 传入配置类,创建IOC容器
  2. 注册配置类,调用refresh,初始化容器
  3. 容器初始化的时候,注册BeanPostProcessor
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
  • 找到容器中,需要创建的BeanPostProcessors
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

  • 分离不同的BeanPostProcessors(implements PriorityOrdered,Ordered)
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  • 优先级顺序
    PriorityOrdered > Ordered > 普通的BeanPostProcessor
  • 最后创建并注册BeanPostProcessor到beanFactory中
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName,BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {              
        internalPostProcessors.add(pp);       
    }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

3. 创建流程

  • 创建BeanPostProcessors实例的流程和创建一般bean实例一样(具体debug过程不详细描述)(AbstractAutowireCapableBeanFactory)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
    //创建bean实例
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    ...
    //给bean的属性赋值
    populateBean(beanName, mbd, instanceWrapper);
    //初始化bean
    if (exposedObject != null) {
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    ...
}
  • bean初始化
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
  //处理Aware接口的方法回调
  invokeAwareMethods(beanName, bean);
  ...
  //调用PostBeanProcessor的postProcessBeforeInitialization
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
  ...
  //执行自定义的初始方法(implements InitializingBean)
  invokeInitMethods(beanName, wrappedBean, mbd);
  ...
  //最后调用PostBeanProcessor的postProcessAfterInitialization
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 2.1 我们的理念是:让别人为你服务 IoC是随着近年来轻量级容器(Lightweight Container)的...
    好好学习Sun阅读 7,632评论 0 11
  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 11,816评论 4 21
  • Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相...
    Theriseof阅读 7,813评论 1 24
  • 为了很久不用 Perl 的人,快点熟悉这门语言: 使用 given .. when 然后就能用: 语句后面的分号 ...
    ssqq阅读 2,962评论 0 1
  • 如果有一天我不复存在了,请不要再询问我去了哪里,或许我是找到了灵魂的归处。
    博弈人阅读 994评论 0 1