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