[译]10-Spring BeanPostProcessor

Spring框架提供了BeanPostProcessor接口,该接口暴露了两个方法postProcessBeforeInitialization(Object bean,String beanName)

和postProcessAfterInitialization(Object bean,String beanName).其中第一参数是经过实例化的bean实例,第二个参数是该bean在

spring IOC容器中的唯一标识.

 

通过实现BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法,我们可以做很多有意义的

事情.postProcessBeforeInitialization方法的调用时机是在bean实例化并装配完毕之后,在调用初始化方法之前;而第二方法调用的时机

是在初始化方法调用之后.为了便于理解,我画了一张图:

 

通过上图可知,我们可以定义多个BeanPostProcessor接口的实现类,多个实现类直接以责任链的方式依次执行.

一般情况下BeanPostProcessor的实现类还会实现org.springframework.core.Ordered接口,Ordered接口的定义了getOrder方法,该方

法的返回值代表该BeanPostProcessor实现类的执行时机(数字越小,越先执行)

 

我们下面写一段例子程序,以上图为原本.程序中会定义三个BeanPostProcessor,三个的作用如下:

红色:LogRecorder,记录日志

蓝色:TimeRecoder,记录执行时间记录

紫色:PermissionCheck,权限检查

 

1.新建com.tutorialspoint.post_processor包,并在包中新建HelloWorld.java类,类的内容如下:

package com.tutorialspoint.post_processor;

public class HelloWorld {
   
   public HelloWorld(){
       System.out.println("constructor invoked ... ");
   }
   private String message;

   public void setMessage(String message){
       System.out.println("set method invoked ... ");
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }

   public void init(){
      System.out.println("init method invoked ... ");
   }

   public void destroy(){
      System.out.println("destroy method invoked ... ");
   }
}

 

2.在包com.tutorialspoint.post_processor中新建上述三个BeanPostProcessor的实现类,三个类的内容分别如下:

LogRecorder.java

package com.tutorialspoint.post_processor;

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

public class LogRecorder implements BeanPostProcessor,Ordered {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        //初始化方法调用之后会回调该方法,在这里可以根据实际需求进行编码。
        System.out.println("Log Info:"+beanName+" has been initailized");
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        //初始化方法调用之前调用该方法.
        System.out.println("Log Info:"+beanName+" is going to be initailized");
        return bean;
    }

    //实现该方法用于指明该BeanPostProcessor的执行时机
    @Override
    public int getOrder() {
        return 1;
    }

}

 

TimeRecoder.java

package com.tutorialspoint.post_processor;

import java.util.Date;

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

public class TimeRecoder implements BeanPostProcessor,Ordered{

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(beanName+" has been initilized,time now is "+new Date());
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(beanName+" is going to be initilized,time now is "+new Date());
        return bean;
    }

    @Override
    public int getOrder() {
        return 2;
    }

}

 

PermissionCheck.java

package com.tutorialspoint.post_processor;

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

public class PermissionCheck implements BeanPostProcessor,Ordered {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(beanName+" has been initailized,permissions checked... ");
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(beanName+" is going to be initailized,begin to check permissions ... ");
        return bean;
    }

    @Override
    public int getOrder() {
        return 3;
    }

}

 

3.在src目录下新建post_processor.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-3.0.xsd">
   
   <bean id="helloWorld" 
         class="com.tutorialspoint.post_processor.HelloWorld" 
         destroy-method="destroy"
         init-method="init">
       <property name="message" value="Hello World!"></property>
   </bean>
   
   <!-- spring容器会检测到实现了BeanPostProcessor接口的bean,并在适当的时机调用适当的方法 -->
   <bean name="logRecorder" class="com.tutorialspoint.post_processor.LogRecorder"></bean>
   
   <bean name="timeRecoder" class="com.tutorialspoint.post_processor.TimeRecoder"></bean>
   
   <bean name="permissionCheck" class="com.tutorialspoint.post_processor.PermissionCheck"></bean>

</beans>

 

4.在com.tutorialspoint.post_processor包中新建MainApp.java,内容如下:

package com.tutorialspoint.post_processor;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("post_processor.xml");
        HelloWorld hw = (HelloWorld)ctx.getBean("helloWorld");
        hw.getMessage();
        ctx.registerShutdownHook();
    }
}

 

5.运行程序,检查结果:

仔细分析运行结果,跟我们预期是一致的!

posted @ 2015-05-05 16:35  sysman  阅读(430)  评论(0编辑  收藏  举报