Spring BeanPostProcessor 詳解

BeanPostProcessor接口:


public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    Object postProcessAfterInitialization(Object bean,  String beanName) throws BeansException;

}

該接口中包含兩個方法。BeanPostProcessor接口的作用:
通過這兩個回調函數來實現自己的實例化邏輯來覆蓋默認的實例化邏輯,依賴注入邏輯等等。你可以實現一個或者多個BeanPostProcessor插件當年想實現自己的某些邏輯在Spring IOC容器對Bean進行了默認初始化以後。
例子1:
Desk.java

package com.mxsm.spring.bean;

import org.springframework.beans.factory.InitializingBean;

public class Desk implements InitializingBean{

    private String width;

    private String hight;

    private String length;


    public Desk(String width, String hight, String length) {
        super();
        this.width = width;
        this.hight = hight;
        this.length = length;
    }

    public Desk() {
        super();
        // TODO Auto-generated constructor stub
    }

    public String getWidth() {
        return width;
    }

    public void setWidth(String width) {
        this.width = width;
    }

    public String getHight() {
        return hight;
    }

    public void setHight(String hight) {
        this.hight = hight;
    }

    public String getLength() {
        return length;
    }

    public void setLength(String length) {
        this.length = length;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("############:1");
    }

    @Override
    public String toString() {
        return "Desk [width=" + width + ", hight=" + hight + ", length="
                + length + "]";
    }
}

TestBeanPostProcessor.java

package com.mxsm.spring.bean.beanpostprocessor;

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

import com.mxsm.spring.bean.Desk;

public class TestBeanPostProcessor implements BeanPostProcessor{

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        // TODO Auto-generated method stub
        System.out.println(beanName+"   ---1");
        if(bean instanceof Desk){
            Desk d = (Desk)bean;
            System.out.println(d.getHight());
        }


        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        // TODO Auto-generated method stub
        System.out.println(beanName+"   ---2");
        if(bean instanceof Desk){
            Desk d = (Desk)bean;
            System.out.println(d.getHight());
        }
        return bean;
    }

}

Spring xml 配置:

<?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 id="beanPostProcessor" class="com.mxsm.spring.bean.beanpostprocessor.TestBeanPostProcessor">
    </bean>

    <bean id="desk_1" class="com.mxsm.spring.bean.Desk">
        <constructor-arg name="hight" value="1.3"/>
        <constructor-arg name="length" value="1.4"/>
        <constructor-arg name="width" value="1.5"/>
    </bean>

</beans>

測試代碼(Junit4進行單元測試):

package com.mxsm.spring;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mxsm.spring.bean.Desk;

public class SpringBeanPostProcessor {

    @Test
    public void testBeanPostProcessor(){

        @SuppressWarnings("resource")
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application_BeanPostProcessor.xml");
        Desk desk1 = applicationContext.getBean("desk_1",Desk.class);
        System.out.println(desk1);

    }

}

代碼測試接口截圖:
這裏寫圖片描述
首先執行的postProcessBeforeInitialization方法,然後執行的是afterPropertiesSet最後執行postProcessAfterInitialization方法。afterPropertiesSet執行的位置要注意。

例子二:
Desk.java 和上面的一樣。
Desk2.java的也一樣代碼。
增加一個配置文件application_BeanPostProcessor2.xml

<?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 id="desk_2" class="com.mxsm.spring.bean.Desk2">
        <constructor-arg name="hight" value="1.888"/>
        <constructor-arg name="length" value="1.9999"/>
        <constructor-arg name="width" value="1.7777"/>
    </bean>

</beans>

測試代碼增加一個方法:

    @Test
    public void testBeanPostProcessor2(){

        @SuppressWarnings("resource")
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application_BeanPostProcessor.xml","application_BeanPostProcessor2.xml");
        Desk2 desk2 = applicationContext.getBean("desk_2",Desk2.class);
        System.out.println(desk2);


    }

測試結果:
這裏寫圖片描述
從這個例子可以看出:只要一個IOC容器定義了其他的容器能進行繼承。

(備註:所有的測試代碼都能在:https://github.com/mxsm找到,項目名稱SpringLearnExamples)

發佈了35 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章