Spring扩展之三:BeanPostProcessor接口


BeanPostProcessor: Bean初始化前后回调。

InstantiationAwareBeanPostProcessor:Bean实例化前后回调。

SmartInstantiationAwareBeanPostProcessor:Bean类型,构造器,以及对Bean的引用回调。

MergedBeanDefinitionPostProcessor:合并Bean Definition后的回调。

DestructionAwareBeanPostProcessor:Bean销毁前的回调。

InitializingBean:自定义初始化方法。

 

BeanPostProcessor

1.介绍

允许自定义修改新的bean实例的工厂钩子函数,例如:检查标记接口或使用代理包装bean。

BPP(Bean Post Processor) Bean是一种特殊的Bean,它是在其他任何Bean之前创建并与新创建的bean交互。

通常,在postProcessBeforeInitialization方法中处理标记器接口,而在postProcessAfterInitialization方法中处理bean。

ApplicationContext可以在其bean定义中自动检测BeanPostProcessor bean,并将这些后处理器应用于随后创建的任何bean。

一个普通的BeanFactory允许以编程方式注册后处理器,并将其应用于通过Bean工厂创建的所有Bean。

主要是处理Bean初始化之前以及初始化之后的回调。

先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。

public interface BeanPostProcessor {
    /**
     * 在任何bean初始化回调之前(例如InitializingBean的afterPropertiesSet或自定义init-method)之前,
     * 将此BeanPostProcessor应用于给定的新bean实例。
     * 返回的Bean实例可能是原始实例的包装。
     * 默认实现按原样返回给定的 bean。
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    /**
     * 在任何bean初始化回调之后(例如InitializingBean的afterPropertiesSet或自定义init-method)之后,
     * 将此BeanPostProcessor应用于给定的新bean实例。
     * 如果是FactoryBean,则将为FactoryBean实例和由FactoryBean创建的对象(从Spring 2.0开始)调用此回调。
     * 可以通过FactoryBean检查相应bean实例来决定是应用到FactoryBean还是FactoryBean创建的对象,还是两者都应用。
     * 返回的Bean实例可能是原始实例的包装。
     * 默认实现按原样返回给定的 bean。
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

2.使用

//注册方式一
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
   // 传入beanFactory
    private final BeanFactory beanFactory;
    
    //注册方式二
    public CustomBeanPostProcessor(BeanFactory beanFactory) {
        System.out.println("CustomBeanPostProcessor 实例化......");
        this.beanFactory = beanFactory;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("spring中bean实例:" + beanName + " 初始化之前处理......");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("spring中bean实例:" + beanName + " 初始化之后处理......");
        if ("person".equals(beanName)){
            Field[] declaredFields = bean.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if ("name".equals(declaredField.getName())){
                    try {
                        //修改对象的属性
                        declaredField.setAccessible(true);
                        declaredField.set(bean,"哈哈哈");
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return bean;
    }
}
// 注册方式二
// 提示信息: is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
// 对于返回Spring BeanFactoryPostProcessor(BFPP)类型或者BeanPostProcessor(BPP)类型的@Bean方法,必须特别注意。 
// 因为BFPP对象必须在容器生命周期的早期实例化,所以它们会干扰@Configuration类中的@Autowired,@ Value和@PostConstruct之类的注释的处理。 
// 为了避免这些生命周期问题,请将BFPP或BPP返回的@Bean方法标记为static
@Bean
public static CustomBeanPostProcessor customBeanPostProcessor(){
    return new CustomBeanPostProcessor(null);
}
//注册方式三
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));

3.注意

  • BeanPostProcessor依赖的bean,不会执行BeanPostProcessor的方法,因为所依赖的Bean需要在BeanPostProcessor之前创建完成。
  • BeanPostProcessor以及依赖的bean无法使用AOP。
  • 当使用ConfigurableBeanFactory接口的addBeanPostProcessor方法手动添加BeanPostProcessor时,只能作用于那些延迟加载的Bean或非单例bean。
  • 当使用addBeanPostProcessor方式添加的BeanPostProcessor,Ordered接口的作用将失效,而是以注册的顺序执行。
  • 在使用@Bean声明工厂方法返回BeanPostProcessor实现类对象时,返回值必须是BeanPostProcessor类型,或者更低级的类型。

4.注册点

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);
        try {
            postProcessBeanFactory(beanFactory);
            // 实例化并调用所有注册的BeanFactoryPostProcessor bean,必须在单例实例化之前调用
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册拦截bean创建的BeanPostProcessor处理器.
 registerBeanPostProcessors(beanFactory);
            initMessageSource();
            initApplicationEventMulticaster();
            onRefresh();
            registerListeners();
            finishBeanFactoryInitialization(beanFactory);
            finishRefresh();
        }
        ...
    }
}

5.触发点

InstantiationAwareBeanPostProcessor

1.介绍

BeanPostProcessor的子接口,在继承BeanPostProcessor的基础上添加了实例化之前,以及实例化之后的回调,但设置了显式属性或发生自动装配之前的回调。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    /*
     * 实例化bean之前回调,如果该方法返回null,后面的方法都正常执行;
     * 如果返回一个非null对象,则bean创建过程将被短路,将直接执行postProcessAfterInitialization方法,(实例化之后和初始化之前都不执行)
     */
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    /**
     * 在实例化bean之后但在发生Spring属性填充(通过显式属性或自动装配)之前回调。
     */
    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    /**
     * 在将属性值应用于bean之前回调
     */
    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        return null;
    }

    // API不推荐使用
    @Deprecated
    @Nullable
    default PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }
}

2.触发点

SmartInstantiationAwareBeanPostProcessor

1.介绍

InstantiationAwareBeanPostProcessor的子接口,在继承InstantiationAwareBeanPostProcessor的基础上添加了返回获取目标对象的类型,构造器,以及对Bean的引用回调。

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

    // 确定给定bean的类型。
    @Nullable
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    // 确定要用于给定bean的候选构造函数。
    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {
        return null;
    }
    // 获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

2.触发点

InstantiationAwareBeanPostProcessorAdapter

1.介绍

实现了SmartInstantiationAwareBeanPostProcessor接口,而SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,InstantiationAwareBeanPostProcessor接口又继承BeanPostProcessor接口;

所以InstantiationAwareBeanPostProcessorAdapter是这些接口的合集。

public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {
    // 确定给定bean的类型。
    @Override
    @Nullable
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    // 确定给定bean的候选构造函数。
    @Override
    @Nullable
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    // 获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
    // bean实例化之前回调
    @Override
    @Nullable
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    // bean实例化之后回调
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }
    // 在将属性值应用于bean之前回调
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        return null;
    }
    // API不推荐使用,废弃
    @Deprecated
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }
    // bean初始化之前回调
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    // bean初始化之后回调
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

MergedBeanDefinitionPostProcessor

1.介绍

BeanPostProcessor的子接口,在继承BeanPostProcessor的基础上添加了对合并Bean Definition后的回调。

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
    // 对指定bean的给定合并bean定义进行后处理
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

    // 重新设置指定名称的Bean定义
    default void resetBeanDefinition(String beanName) {
    }
}

2.说明

例如:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

,RequiredAnnotationBeanPostProcessor都是MergedBeanDefinitionPostProcessor的实现

3.触发点

DestructionAwareBeanPostProcessor

1.介绍

BeanPostProcessor的子接口,在继承BeanPostProcessor的基础上添加了对Bean销毁前的回调。

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
    // 在销毁Bean之前进行处理,仅适用于容器完全管理其生命周期的bean,单例和作用域bean。
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

    // 判断是否需要处理这个对象的销毁
    default boolean requiresDestruction(Object bean) {
        return true;
    }
}

2.触发点

InitializingBean

1.介绍

由bean实现的接口,可以插手Bean的初始化过程来实现自定义初始化。

public interface InitializingBean {
    // 自定义初始化
    void afterPropertiesSet() throws Exception;
}

2.触发点

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        ...
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {throw pae.getException();}
        }
        else {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

 3.注意点

1.Spring提供了两种自定义初始化Bean的方法,一是实现InitializingBean接口,实现afterPropertiesSet方法,二是在配置文件中同过init-method指定,两种方式可以同时使用。

2.如果两个都实现,那只会执行afterPropertiesSet方法。

3.实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖

 

BeanPostProcessor接口调用顺序:

  1. SmartInstantiationAwareBeanPostProcessor-predictBeanType:确定给定bean的类型。

  2. SmartInstantiationAwareBeanPostProcessor-getEarlyBeanReference:提前暴露的bean的引用,用来支持单例对象的循环引用。

  3. InstantiationAwareBeanPostProcessor-postProcessBeforeInstantiation:bean实例化之前回调,如果有返回实例则直接跳转到postProcessAfterInitialization方法。

  4. SmartInstantiationAwareBeanPostProcessor-determineCandidateConstructors:确定给定bean的候选构造函数。

  5. MergedBeanDefinitionPostProcessor-postProcessMergedBeanDefinition:对指定bean的给定合并bean定义进行后处理。

  6. InstantiationAwareBeanPostProcessor-postProcessAfterInstantiation:bean实例化之后回调。

  7. InstantiationAwareBeanPostProcessor-postProcessProperties:将属性值应用于bean之前回调。

  8. BeanPostProcessor-postProcessBeforeInitialization:bean初始化之前回调。

  9. InitializingBean-afterPropertiesSet:自定义初始化方法。

  10. xml中配置的init-method:xml指定的自定义初始化方法。

  11. BeanPostProcessor-postProcessAfterInitialization:bean初始化之后回调。

  12. DestructionAwareBeanPostProcessor-requiresDestruction:确定给定b​​ean实例是否需要此后处理器销毁。

  13. DestructionAwareBeanPostProcessor-postProcessBeforeDestruction:销毁对象前回调。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM