spring的后置处理器——BeanPostProcessor

后置处理器的调用时机

BeanPostProcessor是spring提供的接口,它有两个方法——postProcessBeforeInitialization、postProcessAfterInitialization。关于这两个方法的调用时机,可以参考spring源码注释。

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.*/
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.*/
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

从源码注释中可以看出,postProcessBeforeInitialization方法会在bean实例化和属性设置之后,自定义初始化方法(参考https://www.cnblogs.com/dubhlinn/p/10664402.html提到的3种方式)之前被调用,而postProcessAfterInitialization方法会在自定义初始化方法之后被调用。当容器中存在多个BeanPostProcessor的实现类时,会按照它们在容器中注册的顺序执行。对于自定义BeanPostProcessor实现类,还可以让其实现Ordered接口自定义排序。

后置处理器的注册方式

在ApplicationContext容器中,只需要按普通的bean注册即可;

但是在BeanFactory容器中,需要显示的调用addBeanPostProcessor()方法才能注册。

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

/**
 * 自定义后置处理器
 * 用于在bean的初始化前后进行扩展
 * 这里的初始化,指的是初始化阶段调用的方法,
 * 例如@Bean注解的initMethod、spring提供的InitializingBean接口、jsr-250提供的@PostConstruct接口
 * 当容器中存在多个后置处理器时,默认会按照其在容器中注册的顺序执行
 * 对于自定义后置处理器,也可以通过实现Ordered接口来自定义其执行顺序,数字越大优先级越低
 */
public class AppleBeanPostProcessor implements BeanPostProcessor, Ordered {

    /**
     * 在初始化前执行的扩展逻辑
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("apple".equals(beanName)) {
            System.out.println("创建了苹果对象...");
        }
        return bean;
    }

    /**
     * 在初始化后执行的扩展逻辑
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("apple".equals(beanName)) {
            System.out.println("苹果对象初始化完成...");
        }
        return bean;
    }

    @Override
    public int getOrder() {
        return 3;
    }
}
/**
 * 用注册普通bean的方式注册自定义后置处理器
 */
@Configuration
@Import(value = {AppleBeanPostProcessor.class})
public class LifeBeanConfig2 {
}

后置处理器的作用

简单的说,后置处理器用于bean对象初始化前后进行逻辑增强。spring提供了BeanPostProcessor的很多实现类,例如AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现,AnnotationAwareAspectJAutoProxyCreator用于SpringAOP的动态代理等等。除此之外,我们还可以自定义BeanPostProcessor的实现类,在其中写入需要的逻辑。下面以AnnotationAwareAspectJAutoProxyCreator为例,说明后置处理器是怎样工作的。我们都知道springAOP的实现原理是动态代理,最终放入容器的是代理类的对象,而不是bean本身的对象,那么spring是什么时候做到这一步的?就是在AnnotationAwareAspectJAutoProxyCreator后置处理器的postProcessAfterInitialization方法,即bean对象初始化完成之后,后置处理器会判断该bean是否注册了切面,如果是,则生成代理对象注入容器

    /**
     * Create a proxy with the configured interceptors if the bean is
     * identified as one to proxy by the subclass.
     * @see #getAdvicesAndAdvisorsForBean
     */
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

猜你喜欢

转载自www.cnblogs.com/dubhlinn/p/10668156.html
今日推荐