zoukankan      html  css  js  c++  java
  • spring的后置处理器——BeanPostProcessor以及spring的生命周期

    后置处理器的调用时机

    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;
        }

    spring的生命周期

    所谓spring的生命周期,是指一个bean对象在容器中从创建到销毁的过程,大致会经历如下过程:

    1. 执行bean的构造方法,生成bean对象

    2. 执行bean的set方法,注入属性

    3. 如果容器中存在BeanPostProcessor的实现类,则执行它们的postProcessorBeforeInitialization方法

    4. 如果bean实现了InitializingBean接口,则执行afterPropertiesSet方法

    5. 如果<bean>标签或@Bean注解中定义了init-method/initMethod,则执行其引用的方法

    6. 如果容器中存在BeanPostProcessor的实现类,则执行它们的postProcessorAfterInitialization方法

    7. 关闭容器时,如果bean实现了DisposableBean接口,则执行destroy方法

    8. 关闭容器时,如果<bean>标签或@Bean注解中定义了destroy-method/destroyMethod,则执行其引用的方法

  • 相关阅读:
    CTF-域渗透--SSH服务
    CTF-域渗透--SMB信息泄露
    CTF-域渗透--FTP服务后门利用
    Codeforces Round #628 (Div. 2)
    模板
    模板
    Educational Codeforces Round 6
    Educational Codeforces Round 5
    模板
    Codeforces Round #627 (Div. 3)
  • 原文地址:https://www.cnblogs.com/dubhlinn/p/10668156.html
Copyright © 2011-2022 走看看