美文网首页程序员
Spring BeanPostProcessor接口使用

Spring BeanPostProcessor接口使用

作者: zpwd63 | 来源:发表于2018-01-03 14:18 被阅读0次
    • Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor、BeanFactoryPostProcessor、BeanValidationPostProcessor等一系列后处理器。他们的使用方式大多类似,了解其中一个并掌握他的使用方式,其他的可以触类旁通。

    • 这里以BeanPostProcessor为例展示其使用方式。

    • BeanPostProcessor接口提供了两个供开发者自定义的方法:postProcessBeforeInitialization、postProcessAfterInitialization。

    • postProcessBeforeInitialization:该方法主要针对spring在bean初始化时调用初始化方法前进行自定义处理。

    • postProcessAfterInitialization:该方法主要针对spring在bean初始化时调用初始化方法后进行自定义处理。

    • 示例代码:

    /**
     * 测试bean
     */
    public class Cat {
    
        private String name;
    
        private int age;
    
        public void say() {
            System.out.println("name:" + name);
            System.out.println("age:" + age);
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    /**
     * 自定义后处理器
     */
    public class CatBeanPostProcessor implements BeanPostProcessor {
    
        @Nullable
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof Cat) {
                //输出原始属性
                Cat cat = (Cat) bean;
                cat.say();
                return bean;
            }
            return bean;
        }
    
        @Nullable
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof Cat) {
                //修改属性值,并返回
                Cat cat = (Cat) bean;
                cat.setName("hello maomi");
                cat.setAge(3);
                return cat;
            }
            return bean;
        }
    
    }
    
    /**
     * 运行
     */
    public class Run {
    
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
            Cat cat = (Cat) applicationContext.getBean("cat");
            cat.say();
        }
    
    }
    

    xml配置信息

        <!--配置bean并初始化-->
        <bean id="cat" class="com.source.postprocessor.Cat" >
            <property name="name" value="HelloKitty" />
            <property name="age" value="1" />
        </bean>
    
        <bean id="catBeanPostProcessor" class="com.source.postprocessor.CatBeanPostProcessor" />
    

    输出结果:

    name:HelloKitty
    age:1
    name:hello maomi
    age:3
    
    • 可以看到通过后处理器处理过后的bean信息已经改变。最后,看看源码中如何调用自定义实现的。
      1. 在初始化bean方法中:AbstractAutowireCapableBeanFactory.java
         /**
         * 初始化bean
         */
        protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            //省略部分无关代码
            Object wrappedBean = bean;
            //初始化前
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
      
            try {
                //调用初始化方法初始化bean
                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()) {
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
            return wrappedBean;
        }
      
        //postProcessBeforeInitialization方法调用
        @Override
        public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException {
      
            Object result = existingBean;
            for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
                //调用自定义postProcessBeforeInitialization方法
                Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }
      
        //postProcessAfterInitialization方法调用
        @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
      
            Object result = existingBean;
            for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
                //自定义postProcessAfterInitialization方法调用
                Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }
      
    • 以上就是spring对自定义方法实现的调用过程。

    相关文章

      网友评论

        本文标题:Spring BeanPostProcessor接口使用

        本文链接:https://www.haomeiwen.com/subject/tdyhnxtx.html