Spring的后置处理器是Spring对外开发的重要扩展点,允许我们接入Bean的实例化流程中,以达到动态注册BeanDefinition、动态修改BeanDefinition、动态修改Bean的作用。
BeanFactoryPostProcessor
BeanFactory的后置处理器,在BeandefinitionMap填充完毕之后,Bean实例化之前执行。
BeanFactoryPostProcessor是一个接口规范,用于对BeanDefinition进行操作(注册、修改、删除)。
package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
应用
-
方式一:自定义BeanFactoryPostProcessor接口实现类:实现BeanFactoryPostProcessor接口,并将实现类注册到Spring中,Spring就可以自动调用postProcessBeanFactory方法.
package com.blueStarWei.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.stereotype.Component; @Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 注册 BeanDefinition definition = new RootBeanDefinition(); definition.setBeanClassName("com.blueStarWei.ObjectBeanFactory"); //必须强制转换为DefaultListableBeanFactory才能注册\删除 DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory; defaultListableBeanFactory.registerBeanDefinition("myBeanFactory",definition); //删除 defaultListableBeanFactory.removeBeanDefinition("user"); //修改 BeanDefinition person = beanFactory.getBeanDefinition("person"); person.setScope(BeanDefinition.SCOPE_PROTOTYPE); } }
-
方式二:自定义BeanDefinitionRegistryPostProcessor接口实现类:BeanDefinitionRegistryPostProcessor接口是BeanFactoryPostProcessor接口的子接口,主要用于注册BeanDefinition。【先调用postProcessBeanDefinitionRegistry(),再调用postProcessBeanFactory()】
package com.blueStarWei.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.stereotype.Component; @Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println(">>>>>>>1. postProcessBeanDefinitionRegistry"); BeanDefinition definition = new RootBeanDefinition(); definition.setBeanClassName("com.blueStarWei.ObjectBeanFactory"); registry.registerBeanDefinition("myBeanFactory",definition); } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println(">>>>>>>>>>2. postProcessBeanFactory"); } }
注意:当方式一与方式二同时使用时,调用顺序为:
-
BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
-
BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
-
BeanFactoryPostProcessor.postProcessBeanFactory()
BeanPostProcessor
Bean的后置处理器,一般在Bean的初始化前后执行。Bean实例化之后,填充到单例池singletonObjects之前执行,会进行Bean的初始化。
BeanPostProcessor是一个接口规范,用于对Bean进行修改。
package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; public interface BeanPostProcessor { /** * 在Bean的初始化之前执行 */ Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * 在Bean的初始化之后执行 */ Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
应用
- 使用动态代理进行Bean的功能增强
package com.blueStarWei.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import java.lang.reflect.Proxy; public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * 打印方法调用时间日志 * 注意:使用jdk自带的Proxy只能对有接口的类进行动态代理,直接代理POJO会报类型ClassCastException * */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Object beanProxy = Proxy.newProxyInstance( bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), (proxy, method, args) -> { long startTime = System.currentTimeMillis(); Object result = method.invoke(bean, args); long endTime = System.currentTimeMillis(); System.out.println(beanName + "." + method.getName() + "执行时间:" + (endTime - startTime) + "ms."); return result; } ); return beanProxy; } }