Spring Bean常用擴充套件介面
阿新 • • 發佈:2019-01-04
一、前言
1、Spring框架運用了非常多的設計模式,從整體上看,它的設計嚴格遵循了OCP---開閉原則,即 【1】保證對修改關閉,即外部無法修改Spring整個運作的流程【2】提供對擴充套件開放,即可以通過繼承、實現Spring提供的眾多抽象類與介面來改變類載入的行為
二、BeanNameAware、ApplicationContextAware和BeanFactoryAware
1、實現BeanNameAware介面,在載入過程中可以獲取到該Bean的ID2、實現ApplicationContextAware介面,在載入過程中可以獲取到ApplicationContext上下文 3、實現BeanFactroyAware介面,在載入過程中可以獲取到該Bean的BeanFactory package XXX;
三、InitialingBean和DisposableBean -- 舉例ExtConsumerConfig
1、initialingBean是一個介面,提供了唯一的方法afterpropertiesSet()2、DisposibleBean也是一個介面,提供了唯一的方法destory()
【1】執行順序:介面優先於配置,即initialingBean>init-method;DisposibleBean>destroy-method
【2】執行機制:initialingBean和DisposibleBean底層使用型別強轉.方法名()進行直接呼叫;init-method和destroy-method使用反射 package XX;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Service;@Servicepublicclass InitialingBeanAndDisposableBeanTest implements InitializingBean, DisposableBean { private Integer age; public void setAge(Integer age) { this.age = age; System.out.println("setAge()");//如果在XML中配置了property } @Override public void destroy() throws Exception { System.out.println("desrroy()"); } /** * 當前Bean(InitialingBeanAndDisposableBeanTest)的所有屬性設定完成後呼叫 */ @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet()"); } //以上列印順序:setAge()->afterPropertiesSet()->destroy()}
四、FactoryBean
1、傳統Spring容器載入一個Bean的整個過程都是由Spring控制的,開發者除了設定Bean的相關屬性外,沒有太多自主權 2、FactoryBean改變了這一點,開發者可以個性化的定製自己想要例項化出來的BeanIAnimal介面: publicinterface Animal { public abstract void say();} Cat實現類: publicclass Cat implements Animal { @Override public void say() { System.out.println("cat.say()"); }} Dog實現類: publicclass Dog implements Animal { @Override public void say() { System.out.println("Dog.say()"); }} FactoryBean實現類: package XXX;import org.springframework.beans.factory.FactoryBean;@Servicepublicclass FactoryBeanTest implements FactoryBean<Animal> { private static String name = "cat"; // 可以在xml中配置 @Override public Animal getObject() throws Exception { if("cat".equals(name)){ return new Cat(); }else if ("dog".equals(name)) { return new Dog(); } return null; } @Override public Class<?> getObjectType() { return Animal.class; } @Override public boolean isSingleton() { return true;// 返回單例 }} JunitTest(XML中配置省略,把FactoryBeanTest配置到Bean即可 || 或者用@Service註解): package XX;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;publicclass JunitTest { @Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/spring/beans.xml"); //此處得到的是[email protected],可見得到了具體的實現類 Object object = applicationContext.getBean("factoryTest"); Animal animal = (Animal) object; // 結果為:Cat.say() animal.say(); }}
五、BeanPostProcessor -- 舉例:AnnotationBeanProcessor
1、之前的initializinngBean、DisposableBean、init-method、destroy-method、FactoryBean都是針對單個Bean控制其初始化的操作2、BeanPostProcessor則可以針對每個(所有Bean載入前後都會調下面方法)Bean生成前後執行一些邏輯;有兩個介面:
【1】postProcessorBeforeInitializing:在初始化Bean之前執行
【2】postProcessorAfterInitializing:在初始化Bean之後執行 3、單個Bean生命週期如下(從下面列印日誌可以看出BeanTest類的執行順序):
package XX;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.stereotype.Service;@Servicepublicclass BeanPostProcessorTest implements BeanPostProcessor{ /** * 每個Bean的生成前都會呼叫 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessorTest.postProcessBeforeInitialization()"); return bean; } /** * 每個Bean生成過程中,如果有Bean實現自InitializingBean或者配置了init-method方法,會執行 */ /** * 每個Bean生成後都會呼叫 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessorTest.postProcessAfterInitialization()"); return bean; }}
六、BeanFactoryPostProcessor
1、實現自BeanFactoryPostProcessor,即可以在Spring建立Bean之前,讀取Bean的元屬性,並根據需要對元屬性進行修改,比如將Bean的scope從singleton改變為prototype2、BeanFactoryPostProcessor的優先順序高於BeanPostProcessor
3、BeanFactoryPostProcessor的postProcessorBeanFactory()方法只會執行一次
package XX;import org.springframework.beans.BeansException;import org.springframework.beans.MutablePropertyValues;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableBeanFactory;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.stereotype.Service;@Servicepublicclass BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor { /** * 獲取Bean元屬性並修改等操作 */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("postProcessBeanFactory(...)"); //修改元屬性scope BeanDefinition beanDefinition = beanFactory.getBeanDefinition("systemParamInit"); System.out.println("scope for systemParamInit before : " + beanDefinition.getScope()); beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); System.out.println("scope for systemParamInit after : " + beanDefinition.getScope()); //獲取Bean的屬性引數並列印 MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues(); System.out.println("systemParamInit properties :" + mutablePropertyValues); }}
七、InstantiationAwareBeanPostProcessor
1、InstantiationAwareBeanPostProcessor又代表了另外一個Bean的生命週期:例項化2、例項化 --- 例項化的過程是一個建立Bean的過程,即呼叫Bean的建構函式,單例的Bean放入單例池中
初始化 --- 初始化的過程是一個賦值的過程,即呼叫Bean的setter,設定Bean的屬性
3、之前的BeanPostProcessor作用於2過程,現在這個類則作用於1過程 package XX;import java.beans.PropertyDescriptor;import org.springframework.beans.BeansException;import org.springframework.beans.PropertyValues;import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;import org.springframework.stereotype.Service;@Servicepublicclass InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInitialization()"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInitialization()"); return bean; } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInstantiation()"); return beanClass; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInstantiation()"); return true; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; }}