BeanPostProcessor 后置处理器是 Spring IOC 容器经常使用到的一个特性, 这个 Bean 后置处理器是一个监听器, 可以监听容器触发的 Bean 声明周期事件。 后置处理器向容器注册以后, 容器中管理的 Bean就具备了接收 IOC 容器事件回调的能力。BeanPostProcessor 的使用非常简单, 只需要提供一个实现接口 BeanPostProcessor 的实现类, 然后在 Bean 的配置文件中设置即可。
(1).BeanPostProcessor 的源码如下:
这两个回调的入口都是和容器管理的 Bean 的生命周期事件紧密相关, 可以为用户提供在 Spring IOC容器初始化 Bean 过程中自定义的处理操作。
(2).AbstractAutowireCapableBeanFactory类对容器生成的Bean添加后置处理器
BeanPostProcessor后置处理器的调用发生在SpringIOC容器完成对Bean实例对象的创建和属性的依赖注入完成之后,在对Spring依赖注入的源码分析过程中我们知道,当应用程序第一次调用getBean方法(lazy-init预实例化除外)向SpringIOC容器索取指定Bean时触发SpringIOC容器创建Bean实例对象并进行依赖注入的过程,其中真正实现创建Bean对象并进行依赖注入的方法是AbstractAutowireCapableBeanFactory类的doCreateBean方法,主要源码:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { ........................ //这个 exposedObject 在初始化完成之后返回作为依赖注入完成后的 Bean Object exposedObject = bean; try { //将 Bean 实例对象封装,并且 Bean 定义中配置的属性值赋值给实例对象 populateBean(beanName, mbd, instanceWrapper); //初始化 Bean 对象 exposedObject = initializeBean(beanName, exposedObject, mbd); } ............................ //为应用返回所需要的实例对象 return exposedObject; }从上面的代码中我们知道,为Bean实例对象添加BeanPostProcessor后置处理器的入口的是initializeBean方法。
(3).initializeBean方法为容器产生的Bean实例对象添加BeanPostProcessor后置处理器
同样在AbstractAutowireCapableBeanFactory类中,initializeBean方法实现为容器创建的Bean实例对象添加BeanPostProcessor后置处理器,源码如下:
同样在AbstractAutowireCapableBeanFactory类中,initializeBean方法实现为容器创建的Bean实例对象添加BeanPostProcessor后置处理器,源码如下:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //JDK 的安全机制验证权限 if (System.getSecurityManager() != null) { //实现 PrivilegedAction 接口的匿名内部类 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //为 Bean 实例对象包装相关属性, 如名称, 类加载器, 所属容器等信息 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //对 BeanPostProcessor 后置处理器的 postProcessBeforeInitialization //回调方法的调用, 为 Bean 实例初始化前做一些处理 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try {
//调用 Bean 实例对象初始化的方法, 这个初始化方法是在 Spring Bean 定义配置 //文件中通过 init-Method 属性指定的 //判断是否实现InitializingBean接口
invokeInitMethods(beanName, wrappedBean, mbd);} catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //对 BeanPostProcessor 后置处理器的 postProcessAfterInitialization //回调方法的调用, 为 Bean 实例初始化之后做一些处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}
BeanPostProcessor是一个接口,其初始化前的操作方法和初始化后的操作方法均委托其实现子类来实现,在Spring中,BeanPostProcessor的实现子类非常的多,分别完成不同的操作,如:AOP面向切面编程的注册通知适配器、Bean对象的数据校验、Bean继承属性/方法的合并等等,我们以最简单的AOP切面织入来简单了解其主要的功能。
AdvisorAdapterRegistrationManager 是 BeanPostProcessor 的一个实现类, 其主要的作用为容器中管理的 Bean 注册一个面向切面编程的通知适配器, 以便在 Spring 容器为所管理的 Bean 进行面向切,面编程时提供方便, 其源码:
其他的 BeanPostProcessor 接口实现类的也类似, 都是对 Bean 对象使用到的一些特性进行处理, 或者向 IOC 容器中注册, 为创建的 Bean 实例对象做一些自定义的功能增加, 这些操作是容器初始化 Bean时自动触发的, 不需要认为的干预。
2.InitializingBean源码分析
AbstractAutowireCapableBeanFactory中InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法, 其源码:
1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用。
2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖。
3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
上一篇: 基于 Annotation 的依赖注入
下一篇: DispatcherServlet