zoukankan      html  css  js  c++  java
  • 【spring源码分析】一、BeanPostProcessor

    在spring-beans中org.springframework.beans.factory.config.BeanPostProcessor

    BeanPostProcessor也称为Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。

    public interface BeanPostProcessor {
     //在bean初始化之前执行
       @Nullable
       default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
           return bean;
      }
       //在bean的初始化之后执行
       @Nullable
       default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
           return bean;
      }
    }

    实现原理:探查源码

    1)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

    在创建Bean时,会调起org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)进行初始化

    这时会执行applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization,所以可以通过这两个方法对bean进行包装

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
           Object result = existingBean;

           Object current;
           //遍历当时容器中所有的BeanPostProcessor 一般都是遍历完所有的BeanPostProcessor
           for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
               BeanPostProcessor processor = (BeanPostProcessor)var4.next();
               current = processor.postProcessBeforeInitialization(result, beanName);
               //返回的是null那么我们通过getBean方法将得不到目标Bean ,退出遍历
               if (current == null) {
                   return result;
              }
          }

           return result;
      }

       public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
           Object result = existingBean;

           Object current;
           for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
               BeanPostProcessor processor = (BeanPostProcessor)var4.next();
               current = processor.postProcessAfterInitialization(result, beanName);
               if (current == null) {
                   return result;
              }
          }

           return result;
      }

    应用场景:

    1、解析bean的注解,将注解中的字段转化为属性

    2、统一将属性在执行前,注入bean中,如数据库访问的sqlMap,如严重服务,这样不需要每个bean都配置属性

    3、打印日志,记录时间等。

    常见BeanPostProcessor分析

    ApplicationContextAwareProcessor

    什么时候被注入的?

    org.springframework.context.support.AbstractApplicationContext#refresh核心方法

    //准备beanFactory
    this.prepareBeanFactory(beanFactory);

    org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

    //往beanFactory添加ApplicationContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //往beanFactory添加ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    作用:

    org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization

    org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

    实现了某种Aware接口,就会注入相关属性

    例如:bean实现了ApplicationContextAware接口

    if (bean instanceof ApplicationContextAware) {
      //会调用bean重写的setApplicationContext方法,注入applicationContext
        ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
    }
  • 相关阅读:
    Java连载63-异常处理try...catch...、方法getMessageyu printStackTrace
    Python连载58-http协议简介
    Java连载62-使用throws关键字处理异常
    HTML连载57-相对定位和绝对定位
    Java连载61-异常的机制与分类
    Python连载57- 邮件头和主题、解析邮件
    Java连载60-类之间的六种关系
    [Java] 数据库编程JDBC
    [bug] MySQL-Front连接MySQL 8.0失败
    [bug]mysql: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone
  • 原文地址:https://www.cnblogs.com/mufeng07/p/14129378.html
Copyright © 2011-2022 走看看