最近研究Spring bean的后置处理BeanFactoryPostProcessor和BeanPostProcessor,这两个接口都是spring初始化bean时对外暴露的扩展点。

1、BeanFactoryPostProcessor接口

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

此接口只有一个方法,可以在spring创建bean之前,系应该bean定义的属性。注意,BeanFactoryPostProcessor是在spring加载完成bean定义之后,实例化bean之前执行的,ConfigurrableListableBeanFactory可以获取所有bean的定义信息。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 现获取bean定义
        BeanDefinition bd = beanFactory.getBeanDefinition("testBean");

        // 修改bean的属性
        MutablePropertyValues mpv = bd.getPropertyValues();

        if(mpv.contains("remark")){
            mpv.addPropertyValue("remark","dgfjf");
        }
    }
}

2、BeanPostProcessor接口

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
BeanPostProcessor实在Spring加载了bean定义并且实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:

1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet

2)在bean定义的时候,通过init-method设置的方法

public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在执行初始化方法之前");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("早执行初始化方法之后");
        return bean;
    }
}

3、使用BeanFactoryPostProcessor需要注意的问题

Special consideration must be taken for @Bean methods that return SpringBeanFactoryPostProcessor(BFPP) types. Because BFPP objects must be instantiated very early in thecontainer lifecycle, they can interfere with processing of annotations such as@Autowired,@Value, and @PostConstruct within@Configuration classes. To avoid theselifecycle issues, mark BFPP-returning@Bean methods as static. For example:

     @Bean
     public static PropertyPlaceholderConfigurer ppc() {
         // instantiate, configure and return ppc ...
     }
即当配置时用BeanFactoryPostProcessor的时候,最好的方式是加上static,因为有可能在注入其属性的时候,BeanPostProcessor可能还没有被注册,导致注入失败。

4、在使用ApplicationContext启动spring容器的时候,在AbstractApplicationContext.refresh()方法中,完成相关初始化工作:

spring中BeanFactoryPostProcessor和BeanPostProcessor

此文章参考blog:https://blog.csdn.net/abw986810159/article/details/61196972

分类:

技术点:

相关文章: