您现在的位置是:首页 >技术教程 >再多学一点Spring之BeanPostProcessor与BeanFactoryPostProcessor网站首页技术教程

再多学一点Spring之BeanPostProcessor与BeanFactoryPostProcessor

青铜大神 2024-06-17 10:13:55
简介再多学一点Spring之BeanPostProcessor与BeanFactoryPostProcessor

        我把两个东西放在一起说是为了对比,BeanFactoryPostProcessor被称为前置处理器,BeanPostProcessor被称为后置处理器。对比看的话更容易理解。

先动手写个例子

        前置处理器代码

public class LearnBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Iterator<String> iterator = beanFactory.getBeanNamesIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        for (String beanName : registry.getBeanDefinitionNames()) {
            // 修改BeanDefinition,并重新注册
            BeanDefinition definition = registry.getBeanDefinition(beanName);
            definition.setDescription("my make it mess~~~");
            registry.registerBeanDefinition(beanName, definition);
        }
    }

}

        这里我选择实现了BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor,而不是BeanFactoryPostProcessor的原因是BeanDefinitionRegistryPostProcessor可以修改并重新注册BeanDefinition。而BeanFactoryPostProcessor只能获取他们。

public class LearnBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("LearnBeanPostProcessor -> postProcessBeforeInitialization:" + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("LearnBeanPostProcessor -> postProcessAfterInitialization:" + beanName);
        return bean;
    }
}

        注册到Spring中有两个方式远古版本用xml启动的话,就把他当成bean注册就可以了,也可以使用代码注册的形式。

<bean id="learnBeanFactoryPostProcessor" class="org.happy.spring.processor.LearnBeanFactoryPostProcessor"></bean>

<bean id="learnBeanPostProcessor" class="org.happy.spring.processor.LearnBeanPostProcessor"></bean>
@Configuration
public class PostProcessorConfiguration {

    @Bean
    public static BeanFactoryPostProcessor beanFactoryPostProcessor() {
        return new LearnBeanFactoryPostProcessor();
    }
}

执行时机

        Spring中Bean的生命周期:实例化(Instantiation)、属性赋值(Populate)、初始化(Initialization)、销毁(Destruction)。

        前置处理器BeanFactoryPostProcessor在实例化之前被调用,后置处理器BeanPostProcessor在实例化阶段被调用,由于后置处理器有两个方法postProcessBeforeInitialization和postProcessAfterInitialization,所以后置处理器在每个Bean的实例化阶段会被调用两次。

        这是理论方面的执行时机,落实到代码上的话BeanFactoryPostProcessor的子类执行是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法中执行的,BeanPostProcessor的调用时机是AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsBeforeInitialization方法和applyBeanPostProcessorsAfterInitialization方法。

能做什么

        前置处理器可以修改BeanDefinition,所以Spring原生的PropertyPlaceholderConfigurer作用是替换占位符${jdbc.url}。后置处理器可以管理Bean对象,比如InitDestroyAnnotationBeanPostProcessor作用是在Bean对象实例化后执行initMethod。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。