Spring中的後置處理器BeanPostProcessor講解

BeanPostProcessor接口做用:html

若是咱們想在Spring容器中完成bean實例化、配置以及其餘初始化方法先後要添加一些本身邏輯處理。咱們須要定義一個或多個BeanPostProcessor接口實現類,而後註冊到Spring IoC容器中。面試

package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * bean後置處理器
 * @author zss
 *
 */
public class PostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        if ("narCodeService".equals(beanName)) {//過濾掉bean實例ID爲narCodeService
            return bean;
        }
        System.out.println("後置處理器處理bean=【"+beanName+"】開始");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        if ("narCodeService".equals(beanName)) {
            return bean;
        }
        System.out.println("後置處理器處理bean=【"+beanName+"】完畢!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

}

注意:接口中兩個方法不能返回null,若是返回null那麼在後續初始化方法將報空指針異常或者經過getBean()方法獲取不到bena實例對象,由於後置處理器從Spring IoC容器中取出bean實例對象沒有再次放回IoC容器中!spring

將Spring的後置處理器PostProcessor配置到Spring配置文件中性能優化

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 定義一個bean -->
     <bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
     </bean>
    <bean id="beanLifecycle" class="com.test.spring.BeanLifecycle" init-method="init" destroy-method="close">
        <property name="name" value="張三"></property>
        <property name="sex" value="男"></property>
    </bean>

    <!-- Spring後置處理器 -->
    <bean id="postProcessor" class="com.test.spring.PostProcessor"/>
</beans>

BeanPostProcessor API:架構

public interface BeanPostProcessor {  
  
    //實例化、依賴注入完畢,在調用顯示的初始化以前完成一些定製的初始化任務  
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  
     
    //實例化、依賴注入、初始化完畢時執行  
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
  
}

由API能夠看出:
1:後置處理器的postProcessorBeforeInitailization方法是在bean實例化,依賴注入以後及自定義初始化方法(例如:配置文件中bean標籤添加init-method屬性指定Java類中初始化方法、
@PostConstruct註解指定初始化方法,Java類實現InitailztingBean接口)以前調用
2:後置處理器的postProcessorAfterInitailization方法是在bean實例化、依賴注入及自定義初始化方法以後調用併發

注意:
1.BeanFactory和ApplicationContext兩個容器對待bean的後置處理器稍微有些不一樣。ApplicationContext容器會自動檢測Spring配置文件中那些bean所對應的Java類實現了BeanPostProcessor
接口,並自動把它們註冊爲後置處理器。在建立bean過程當中調用它們,因此部署一個後置處理器跟普通的bean沒有什麼太大區別。app

2.BeanFactory容器註冊bean後置處理器時必須經過代碼顯示的註冊,在IoC容器繼承體系中的ConfigurableBeanFactory接口中定義了註冊方法
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

Spring如何調用多個BeanPostProcessor實現類:分佈式

咱們能夠在Spring配置文件中添加多個BeanPostProcessor(後置處理器)接口實現類,在默認狀況下Spring容器會根據後置處理器的定義順序來依次調用。ide

在此我向你們推薦一個架構學習交流圈子。點擊便可加入學習交流圈 裏面資深架構師會分享一些整理好的錄製視頻錄像和BATJ面試題:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多。微服務

Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- bean定義 -->    
    <bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
    </bean>
    <bean id="postProcessor" class="com.test.spring.PostProcessor"/>
    <bean id="postProcessorB" class="com.test.spring.PostProcessorB"/>
</beans>

BeanPostProcessor實現類:

package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * bean後置處理器
 * @author zss
 *
 */
public class PostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("後置處理器處理bean=【"+beanName+"】開始");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("後置處理器處理bean=【"+beanName+"】完畢!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }
}
----------------------------------------------------------------------------------------------------------------------------------------
package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class PostProcessorB implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("後置處理器開始調用了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("後置處理器調用結束了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }
}
Test case:

package com.test.spring;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class T {
    AbstractApplicationContext applicationcontext=null;
    @Before
    public void before() {
        System.out.println("》》》Spring ApplicationContext容器開始初始化了......");
        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});
        System.out.println("》》》Spring ApplicationContext容器初始化完畢了......");
    }
    @Test
    public void  test() {
        applicationcontext.registerShutdownHook();   
    }
}

測試結果:

》》》Spring ApplicationContext容器開始初始化了......
2017-03-19 10:50:29 INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy
2017-03-19 10:50:29 INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
後置處理器處理bean=【narCodeService】開始
後置處理器開始調用了
後置處理器處理bean=【narCodeService】完畢!
後置處理器調用結束了
》》》Spring ApplicationContext容器初始化完畢了......
2017-03-19 10:50:34 INFO:ClassPathXmlApplicationContext-Closing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy
在Spring機制中能夠指定後置處理器調用順序,經過讓BeanPostProcessor接口實現類實現Ordered接getOrder方法,該方法返回一整數,默認值爲 0,優先級最高,值越大優先級越低。

文章出處:https://www.cnblogs.com/deity...做者:情陌人灬已不在

相關文章
相關標籤/搜索