Spring源码-BeanPostProcessor

简介: `BeanPostProcessor `是 Spring 容器给我们提供的一个扩展接口。一般称为`Bean的后置处理器`,可以在创建每个 Bean 的过程中进行干涉,详细点的说就是在 Bean 的实例化前后、Bean的初始化前后,使用我们自定义的逻辑。并且是属于`AbstractBeanFactory`中一个属性。

BeanPostProcessor

BeanPostProcessor 是 Spring 容器给我们提供的一个扩展接口。一般称为Bean的后置处理器,可以在创建每个 Bean 的过程中进行干涉,详细点的说就是在 Bean 的实例化前后、Bean的初始化前后,使用我们自定义的逻辑。并且是属于AbstractBeanFactory中一个属性。

我们先来看下BeanPostProcessor的定义:

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

可以看到,BeanPostProcessor接口中只有两个默认方法,这两个方法有着相同的参数:

  • bean:实例化之后的bean对象
  • beanName:bean名称

这两个默认方法的方法名称只有点小区别,一个是Before,一个是After。还要注意 Initialization,意思是初始化,需要小心与 Instantiation 实例化进行区分。注意:接口中的两个方法是可以返回 null 的哟。只是如果返回 null 不会再执行后续的 BeanPostProcessor

  • 初始化前方法源码
@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
               
        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // BPP1--》BPP2-->BPP3
            // 执行postProcessBeforeInitialization方法,也就是初始化前方法
            Object current = processor.postProcessBeforeInitialization(result, beanName);
                        //执行 postProcessBeforeInitialization 方法返回 null
                        //返回上次结果
            if (current == null) {
                            return result;
            }
            result = current;
        }
        return result;
    }
  • 初始化后方法源码
@Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 执行postProcessAfterInitialization方法,也就是初始化后方法
            Object current = processor.postProcessAfterInitialization(result, beanName);
                        //执行 postProcessAfterInitialization 方法返回 null
                        //返回上次结果
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

两个方法都位于 AbstractAutowireCapableBeanFactory类中。

使用

下面就来写一个简单的示例,来看看BeanPostProcessor的作用

第一步

定义两个对象,User 和 Person

public class Person {

    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}


public class User {
}

第二步

定义一个BeanPostProcessor的实现类,重写其接口方法:

public class MeBeanPostPorcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("初始化前====》" + "当前对象:" + bean + ",beanName = " + beanName);
            return new User();
        }
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("初始化后====》" + "当前对象:" + bean + ",beanName = " + beanName);
            return new Person("gongjie");
        }
        return null;
    }
}

稍稍说一下上面两个方法的逻辑,两个方法中都有一个判断,如果当前 beanName 等于 person 时,才进行干涉。因为 BeanPostProcessor 会在每个 Bean 的创建过程中都会被执行,但某些时候我们可能只需要某个 Bean 被自定义。在 Before方法中进行打印日志,创建User对象返回。After 方法,打印日志并创建Person对象并进行赋值后返回。

第三步

进行 xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.gongj.bean.Person" id="person"></bean>
    <bean class="com.gongj.bean.User" id="user"></bean>
    
</beans>

第四步

编写测试类,进行测试

public static void main(String[] args) {
        ClassPathResource resource = new ClassPathResource("spring-config.xml");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);
        Object person = factory.getBean("person");

        System.out.println(person);
    }

结果:
Person{name='null'}

从运行结果可以看到,没有执行 postProcessBeforeInitializationpostProcessAfterInitialization!这是为什么呢?这与我们使用的容器有关。这里使用的是BeanFactory容器。而不是使用的ApplicationContext。两者之间的区别请前往:Spring源码(三)-BeanFactory

那怎么解决呢!开篇有提到,BeanPostPorcessor是属于AbstractBeanFactory中一个属性。

    private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

既然是一个 List,那就会有add方法,在类 AbstractBeanFactory中看找到了如下代码:

@Override
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            // 是否有InstantiationAwareBeanPostProcessor
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            // 是否有DestructionAwareBeanPostProcessor
            this.hasDestructionAwareBeanPostProcessors = true;
        }
        // Add to end of list
        // 添加到 beanPostProcessors 中,到时候会按添加的顺序执行
        this.beanPostProcessors.add(beanPostProcessor);
    }

所以只需要显示调用 addBeanPostProcessor() 就可以了,加入如下代码:

MeBeanPostPorcessor meBeanPostPorcessor = new MeBeanPostPorcessor();
factory.addBeanPostProcessor(meBeanPostPorcessor);

结果:
初始化前====》当前对象:Person{name='null'},beanName = person
初始化后====》当前对象:com.gongj.bean.User@49097b5d,beanName = person
Person{name='gongjie'}

可以看到,实现BeanPostPorcessorMeBeanPostPorcessor影响了Bean的初始化过程,并使用我们自定义的逻辑。


当然你也可以使用 ApplicationContext,修改代码。

配置文件新增 bean:

    <bean class="com.gongj.beanPostPorcessor.MeBeanPostPorcessor" 
        id="meBeanPostPorcessor"></bean>

Main方法:

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        Object person = context.getBean("person");
        System.out.println(person);
    }
结果:
初始化前====》当前对象:Person{name='null'},beanName = person
初始化后====》当前对象:com.gongj.bean.User@7a07c5b4,beanName = person
Person{name='gongjie'}

这是怎么实现的呢?其实在我们在构建ClassPathXmlApplicationContext 实例对象的时候, 其中refresh方法会调用 registerBeanPostProcessors()方法。这个方法会将检测到的 BeanPostProcessor 注入到 ClassPathXmlApplicationContext 容器中。

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 省略一大部分代码
                // 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中
                registerBeanPostProcessors(beanFactory);
            }
            // 省略
    }
// 实例化并注册所有BeanPostProcessor Bean
// 必须在应用程序bean的任何实例化之前被调用
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }


public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        // 获取BeanPostProcessor类型的bean名称
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 记录beanProcessor的数量
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 将实现 PriorityOrdered 的 BeanPostProcessor 放在一起
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // MergedBeanDefinitionPostProcessor
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        // 将实现 Ordered  的 BeanPostProcessor 放在一起
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 没有实现其他接口的BeanPostProcessor(没有顺序)
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();

        for (String ppName : postProcessorNames) {
            //  将实现了 PriorityOrdered 的 BeanPostProcessor 添加到 priorityOrderedPostProcessors 集合中
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 调用 getBean 获取 bean 实例对象
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    // 实现了 MergedBeanDefinitionPostProcessor
                    internalPostProcessors.add(pp);
                }
            }
            //  将实现了 Ordered 的 BeanPostProcessor 添加到 orderedPostProcessorNames 集合中
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                //无序,按照添加顺序执行
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, register the BeanPostProcessors that implement PriorityOrdered.
        // 首先,注册实现PriorityOrdered的BeanPostProcessor
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 把priorityOrderedPostProcessors添加到beanFactory中
        // 也是调用 AbstractBeanFactory 类中的 addBeanPostProcessor方法
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // Next, register the BeanPostProcessors that implement Ordered.
        // 接下来,注册实现Ordered的BeanPostProcessor
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String ppName : orderedPostProcessorNames) {
            // 调用 getBean 获取 bean 实例对象
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 实现了 MergedBeanDefinitionPostProcessor
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 把orderedPostProcessors添加到beanFactory中
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // Now, register all regular BeanPostProcessors.
        // 现在,注册所有常规BeanPostProcessor
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String ppName : nonOrderedPostProcessorNames) {
            // 调用 getBean 获取 bean 实例对象
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 实现了 MergedBeanDefinitionPostProcessor
                internalPostProcessors.add(pp);
            }
        }
        // 注册
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // Finally, re-register all internal BeanPostProcessors.
        // 最后,重新注册所有内部BeanPostProcessor。也就是 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        //重新注册用于将内部bean检测的ApplicationListener的后处理器,
        //将其移到处理器链的末尾(用于拾取代理等)。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

registerBeanPostProcessors方法首先从 BeanFactory 获取所有 BeanPostProcessor 类型的beanName,然后循环这些 beanName,将其按照PriorityOrderedOrdered无序的顺序添加至相应的 List 集合中,对相应的 List 集合进行sortPostProcessors()排序和 registerBeanPostProcessors注册。
这个排序只有实现了 PriorityOrderedOrderedBeanPostProcessor 才会进行排序操作。会根据getOrder方法中指定的order值进行排序。order值越大,优先级越小

小结:

使用ApplicationContext容器的 BeanPostProcessor 是支持 PriorityOrderedOrdered,也就是说可以指定BeanPostProcessor的执行顺序。而 BeanFactory容器的 BeanPostProcessor 是不支持的,原因在于ApplicationContext容器在启动时会对 BeanPostProcessor 进行 PriorityOrderedOrdered检测并完成排序,而 BeanFactory 中的 BeanPostProcessor 只跟注册的顺序有关,也就是显示调用 addBeanPostProcessor()方法。


子类

这里再介绍几个比较熟悉的子类:

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口是BeanPostProcessor的子接口,通过接口类名我们可以知道它作用:感知 Bean 实例化的后置处理器。它在BeanPostProcessor的基础上新增了几个方法,如下:

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    /*实例化前*/
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    
    /*实例化后*/
    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }
    
    /*对属性值进行修改*/
    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {

        return null;
    }

    @Deprecated
    @Nullable
    default PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

        return pvs;
    }

}

可以看到, InstantiationAwareBeanPostProcessor 接口中有四个默认方法,接下来就分别介绍几个方法的用途,当然 postProcessPropertyValues 方法就不再介绍了,该方法已经过时了。

  • postProcessBeforeInstantiation:实例化前,是 BeanPostProcessor 里最被先执行的方法。在目标对象实例化之前调用,该方法的返回值类型是Object。如果该方法的返回值不为空,则 postProcessAfterInitialization (初始化后)方法会被调用,其它方法不再调用,Spring 创建Bean的流程结束;如果为空,则按照正常的创建Bean流程走(方法默认返回空)。
  • postProcessAfterInstantiation:实例化后,在目标对象实例化之后调用。该方法的返回值类型是 boolean。如果返回值为 false,不会进行属性填充操作。
  • postProcessProperties:修改 Bean 中属性的内容。如果postProcessAfterInstantiation实例化后方法返回 false,该方法不会被调用。

    实例

    创建类并实现 InstantiationAwareBeanPostProcessor,重写其方法。

public class MyBeanPostPorcessor implements InstantiationAwareBeanPostProcessor {
    
    // 如果 postProcessBeforeInstantiation 实例化前方法 返回 不是 null
    // 如我这写法,将会中断 Spring 的创建 bean 的流程,执行完实例化前方法后
    // 直接执行 postProcessAfterInitialization 初始化后方法
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if("person".equals(beanName)){
            System.out.println("实例化前");
            System.out.println("原本class对象:"+beanClass);
        }
        return new User();
        
    }

    // postProcessAfterInstantiation 实例化后 方法,
    // 如果返回 false,将不会对属性进行填充
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

        if("person".equals(beanName)){
            System.out.println("实例化后");
        }
        return false;
    }

    // postProcessAfterInstantiation 实例化后 方法,
    // 如果返回 false,将不会执行 postProcessProperties 方法
   @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("postProcessProperties方法被执行");
            PropertyValue name = pvs.getPropertyValue("name");
            Object oldValue = name.getValue();
            System.out.println("修改前name的值是:"+oldValue);
            name.setConvertedValue("yuanj");
        }
        return pvs;
    }

      // 如果 postProcessProperties 返回 null,将会执行 postProcessPropertyValues 方法
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("废弃方法:postProcessPropertyValues被执行");
            PropertyValue name = pvs.getPropertyValue("name");
            Object oldValue = name.getValue();
            System.out.println("修改前name的值是:"+oldValue);
            name.setConvertedValue("gongjie LOVE  yuanj");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("初始化前");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if("person".equals(beanName)){
            System.out.println("初始化后");
            System.out.println("原本class对象:"+bean);
        }
        return bean;
    }
}

原本的Person类也进行小改动,增加 user属性以及 name 属性的get/set方法,来测试postProcessAfterInstantiation 实例化后方法的返回值是否会影响属性填充。

public class Person {

    @Autowired
    public User user;

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
      System.out.println("setName方法 = " + name);
          this.name = name;
    }
    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "user=" + user +
                ", name='" + name + '\'' +
                '}';
    }
}

xml 新增配置,将之前的 MeBeanPostPorcessor进行注释

<bean class="com.gongj.bean.Person" id="person">
    <property name="name" value="gongj"></property>
</bean>
<bean class="com.gongj.bean.User" id="user"></bean>
<bean class="com.gongj.beanPostPorcessor.MyBeanPostPorcessor" id="myBeanPostPorcessor"></bean>
<context:annotation-config></context:annotation-config>

启动类:

public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        Object person = context.getBean("person");
        System.out.println( "最终对象:" + person);
    }
结果:
实例化前
原本class对象:class com.gongj.bean.Person
初始化后
原本class对象:com.gongj.bean.User@4d76f3f8
最终对象:com.gongj.bean.User@4d76f3f8

根据打印的信息可以看出,只执行了实例化前方法和初始化后方法,并且返回值为实例化前方法的返回值。说明 postProcessBeforeInstantiation实例化前方法的返回值会影响 Spring 创建 Bean 的流程。


  • 修改代码,将 postProcessBeforeInstantiation实例化前方法的返回值修改为 null
@Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if("person".equals(beanName)){
            System.out.println("实例化前");
            System.out.println("原本class对象:"+beanClass);
        }
        //return new User();
        return null;
    }
结果:
实例化前
原本class对象:class com.gongj.bean.Person
实例化后
初始化前
初始化后
原本class对象:Person{user=null, name='null'}
最终对象:Person{user=null, name='null'}

修改 postProcessBeforeInstantiation实例化前方法的返回值之后,执行了实例化后初始化前逻辑。也就是走了 Spring 自带的创建 Bean 的流程。但是我们可以看到最终对象的打印信息里面的 user 属性为 null 值。上面提到 postProcessAfterInstantiation实例化后方法的返回值为false时,不会进行属性填充。


  • 修改代码,将 postProcessAfterInstantiation实例化后方法的返回值修改为 true。
@Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

        if("person".equals(beanName)){
            System.out.println("实例化后");
        }
        return true;
    }

结果:====》
实例化前
原本class对象:class com.gongj.bean.Person
实例化后
postProcessProperties方法被执行
修改前name的值是:TypedStringValue: value [gongj], target type [null]
setName方法 = yuanj
初始化前
初始化后
原本class对象:Person{user=com.gongj.bean.User@7e0b37bc, name='yuanj'}
最终对象:Person{user=com.gongj.bean.User@7e0b37bc, name='yuanj'}

看到打印出来的信息,postProcessProperties方法对 Bean 中属性值的修改是成功的。但我们发现被废弃的方法postProcessPropertyValues并没有被执行,这个方法是完全没有被使用了吗?其实不是的,当 postProcessProperties方法的返回值为 null时,被废弃的方法 postProcessPropertyValues就会被执行。

  • 修改 postProcessProperties方法的返回值为 null。
@Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if("person".equals(beanName)){
            System.out.println("postProcessProperties方法被执行");
            PropertyValue name = pvs.getPropertyValue("name");
            Object oldValue = name.getValue();
            System.out.println("修改前name的值是:"+oldValue);
            name.setConvertedValue("yuanj");
        }
        return null;
    }
结果:=====
实例化前
原本class对象:class com.gongj.bean.Person
实例化后
postProcessProperties方法被执行
修改前name的值是:TypedStringValue: value [gongj], target type [null]
废弃方法:postProcessPropertyValues被执行
修改前name的值是:TypedStringValue: value [gongj], target type [null]
setName方法 = gongjie LOVE  yuanj
初始化前
初始化后
原本class对象:Person{user=com.gongj.bean.User@61e717c2, name='gongjie LOVE  yuanj'}
最终对象:Person{user=com.gongj.bean.User@61e717c2, name='gongjie LOVE  yuanj'}

MergedBeanDefinitionPostProcessor

MergedBeanDefinitionPostProcessor接口是BeanPostProcessor的子接口,用于寻找注入点,所谓注入点其实就是被Spring所支持的注解所标记的属性或者方法,在AbstractAutowireCapableBeanFactory类的doCreateBean方法中,Bean 被实例化之后就会调用applyMergedBeanDefinitionPostProcessors方法。执行该后置处理器的postProcessMergedBeanDefinition方法。`MergedBeanDefinitionPostProcessor有许多的子类,其中两个比较重要,分别是 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                // AutowiredAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor接口.
                // 该PostPorcessor会将被@Autowired、@Value、@Inject 标记的成员变量进行记录.(静态方法、静态属性、无参方法不会作为注入点)
                // CommonAnnotationBeanPostProcessor 也是MergedBeanDefinitionPostProcessor的一个实现.
                // 该类负责记录@Resource、@PostConstruct、@PreDestroy.
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor实现了 MergedBeanDefinitionPostProcessor,作用是查找bean中的被@Autowired@Value 注解标注的属性与方法,如果有javax.inject.Inject依赖,那么也会查找被@Inject注解标注的属性与方法, 封装成InjectionMetadata对象。

CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor继承了 InitDestroyAnnotationBeanPostProcessor类。而InitDestroyAnnotationBeanPostProcessor类实现了MergedBeanDefinitionPostProcessor

作用与 AutowiredAnnotationBeanPostProcessor大致相同,只不过针对的是不同的注解。常见的注解有@PostConstruct@PreDestroy@Resource。如果有相对应的依赖,也可以使用@WebServiceRef@EJB,也会被封装成InjectionMetadata对象。

ApplicationContextAwareProcessor

ApplicationContextAwareProcessor实现了BeanPostProcessor接口。并只重新定义了postProcessBeforeInitialization初始化前方法。

class ApplicationContextAwareProcessor implements BeanPostProcessor {

    private final ConfigurableApplicationContext applicationContext;

    private final StringValueResolver embeddedValueResolver;


    /**
     * Create a new ApplicationContextAwareProcessor for the given context.
     * 为给定上下文创建一个新的ApplicationContextAwareProcessor
     */
    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }


    // 初始化前方法
    @Override
    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
            return bean;
        }

        AccessControlContext acc = null;

        if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            // 具体逻辑在这个方法中
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    //设置bean对应的属性值
    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }

}

如果当前 bean 实现了什么接口,就给这个 bean setter 相对应的对象实例。

DestructionAwareBeanPostProcessor

在销毁 Bean 前执行 Bean 所声明的自定义销毁方法,该回调只能应用到单例Bean。

具体实现之一: InitDestroyAnnotationBeanPostProcessor:调用@PreDestroy注解的销毁方法。

SmartInstantiationAwareBeanPostProcessor

继承自InstantiationAwareBeanPostProcessor,是InstantiationAwareBeanPostProcessor接口的扩展。此接口是一个专用接口,主要用于 Spring 框架内部使用。你会在源码的很多地方见到它。

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

    // 预测此处理器的postProcessBeforeInstantiation(实例化前)回调最终返回的bean的类型。
    @Nullable
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    // 确定要用于给定bean的候选构造函数,具体实现在:AutowiredAnnotationBeanPostProcessor
    // 如果方法返回的结果不为 null,则使用该构造函数数组进行对象实例化
    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {

        return null;
    }
    // 提前暴露引用,用于解决循环依赖问题.
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }

}
  • 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。
相关文章
|
8天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
166 24
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
2月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
161 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
2月前
|
XML 缓存 Java
手写Spring源码(简化版)
Spring包下的类、手写@ComponentScan注解、@Component注解、@Autowired注解、@Scope注解、手写BeanDefinition、BeanNameAware、InitializingBean、BeanPostProcessor 、手写AnnotationConfigApplicationContext
手写Spring源码(简化版)
|
24天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
24天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
117 9
|
1月前
|
设计模式 JavaScript Java
Spring 事件监听机制源码
Spring 提供了事件发布订阅机制,广泛应用于项目中。本文介绍了如何通过自定义事件类、订阅类和发布类实现这一机制,并展示了如何监听 SpringBoot 启动过程中的多个事件(如 `ApplicationStartingEvent`、`ApplicationEnvironmentPreparedEvent` 等)。通过掌握这些事件,可以更好地理解 SpringBoot 的启动流程。示例代码展示了从事件发布到接收的完整过程。
|
1月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
20 1
|
1月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
23 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码