您的位置:首页 > 编程语言 > Java开发

Spring BeanPostProcessor接口 (在Spring实例化bean的前后执行一些附加操作) .

2013-01-30 15:56 666 查看
在Spring实例化bean的前后执行一些附加操作。

有时,你会发现需要立刻在Spring实例化一个bean的前后执行一些附件操作。这些操作可以简单到修改一个bean,也可以复杂到返回一个完全不同的对象。

BeanPostProcessor接口包含两个method:

postProcessBeforeInitialization方法:在Spring调用任何bean的初始化钩子(例如InitializingBean.afterPropertiesSet或者init方法)之前被调用。

postProcessAfterInitialization方法:Spring在成功完成嵌入初始化以后调用他。

例子1:

我们声明了一个实现了BeanPostProcessor接口的类InitDestroyAnnotationBeanPostProcessor,这个类支持声明式的指定注解规则(默认为JSR 250注解)

public class SimpleBean
{

@PostConstruct

public void initialize()
{

System.out.println("Initializing
bean " + getClass());

}

@PreDestroy

public void cleanUp()
{

System.out.println("Cleaning
up bean " + getClass());

}

}

配置:

view
plaincopy
to clipboardprint?

<?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="simpleBean" class="com.apress.prospring2.ch04.bpp.SimpleBean"/>

<bean id="bpp" class="org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor">

<property name="initAnnotationType" value="javax.annotation.PostConstruct"/>

<property name="destroyAnnotationType" value="javax.annotation.PreDestroy"/>

</bean>

</beans>

调用:

view
plaincopy
to clipboardprint?

public class SimpleBeanDemo
{

public static void main(String[]
args) {

ConfigurableListableBeanFactory beanFactory
= new XmlBeanFactory(

new ClassPathResource("/META-INF/spring/bpp-context.xml")

);

registerPostProcessor(beanFactory, "bpp");

SimpleBean sb = (SimpleBean)beanFactory.getBean("simpleBean");

System.out.println(sb);

beanFactory.destroySingletons();

}

private static void registerPostProcessor(ConfigurableListableBeanFactory
beanFactory, String beanName) {

BeanPostProcessor bpp = (BeanPostProcessor)
beanFactory.getBean(beanName);

beanFactory.addBeanPostProcessor(bpp);

}

}

例子2:自己实现一个BeanPostProcessor接口(改变bean的一个字段数据)

(例子的实现是像上面的例子一样,自己定义一个时间注解的实现)


view
plaincopy
to clipboardprint?

package cn.partner4java.beanpostprocessor;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

*
声明一个运行时字段注解

*
@author partner4java

*

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

public @interface TimeStamp
{

}

view
plaincopy
to clipboardprint?

package cn.partner4java.beanpostprocessor;

import java.util.Date;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

/**

*
指定交给Spring管理的bean

*
@author partner4java

*

*/

public class SimpleBean
{

//自定义的注解

@TimeStamp

Date createDate;

//spring中InitDestroyAnnotationBeanPostProcessor实现对bean
init替代的注解

@PostConstruct

public void initialize(){

System.out.println("initialize:
" + getClass());

}

//spring中InitDestroyAnnotationBeanPostProcessor实现对bean
destory替代的注解

@PreDestroy

public void cleanup(){

System.out.println("cleanup:
" + getClass());

}

@Override

public String
toString() {

return "SimpleBean
[createDate=" + createDate + "]";

}

}

编写一个BeanPostProcessor来检查每一个bean并为他们注解了日志字段设置当前日期:

view
plaincopy
to clipboardprint?

package cn.partner4java.beanpostprocessor;

import java.lang.reflect.Field;

import java.util.Date;

import org.springframework.beans.BeansException;

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

import org.springframework.util.ReflectionUtils;

/**

*
编写一个BeanPostProcessor来检查每一个bean并为他们注解了日志字段设置当前日期

*
@author partner4java

*

*/

public class TimestampingBeanPostProcessor implements BeanPostProcessor
{

public Object
postProcessBeforeInitialization(final Object
bean, String beanName)

throws BeansException
{

ReflectionUtils.doWithFields(bean.getClass(),

new ReflectionUtils.FieldCallback()
{

public void doWith(Field
field) throws IllegalArgumentException,

IllegalAccessException
{

field.set(bean, new Date());

}

}, new ReflectionUtils.FieldFilter()
{

public boolean matches(Field
field) {

return field.getType()
== Date.class &&
field.getAnnotation(TimeStamp.class)
!= null;

}

});

return bean;

}

public Object
postProcessAfterInitialization(Object bean, String beanName)

throws BeansException
{

return bean;

}

}

配置文件:

view
plaincopy
to clipboardprint?

<?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="simpleBean" class="cn.partner4java.beanpostprocessor.SimpleBean"/>

<bean id="bpp1" class="org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor">

<property name="initAnnotationType" value="javax.annotation.PostConstruct"/>

<property name="destroyAnnotationType" value="javax.annotation.PreDestroy"/>

</bean>

<bean id="bpp2" class="cn.partner4java.beanpostprocessor.TimestampingBeanPostProcessor"/>

</beans>

调用:

view
plaincopy
to clipboardprint?

package cn.partner4java.beanpostprocessor;

import javax.annotation.PreDestroy;

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

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import org.springframework.beans.factory.xml.XmlBeanFactory;

import org.springframework.core.io.ClassPathResource;

public class SimpleBeanDemo
{

public static void main(String[]
args) {

ConfigurableListableBeanFactory beanFactory
= new XmlBeanFactory(

new ClassPathResource("/META-INF/spring/spring-beanpostprocessor.xml")

);

registerPostProcessor(beanFactory, "bpp1");

registerPostProcessor(beanFactory, "bpp2");

SimpleBean sb = (SimpleBean)beanFactory.getBean("simpleBean");

System.out.println(sb);

//@PreDestroy是被这个方法调用执行的

beanFactory.destroySingletons();

}

private static void registerPostProcessor(ConfigurableListableBeanFactory
beanFactory, String beanName) {

BeanPostProcessor bpp = (BeanPostProcessor)
beanFactory.getBean(beanName);

beanFactory.addBeanPostProcessor(bpp);

}

}

//后台打印:

//initialize:
class cn.partner4java.beanpostprocessor.SimpleBean

//SimpleBean
[createDate=Tue Nov 15 16:18:33 CST 2011]

//cleanup:
class cn.partner4java.beanpostprocessor.SimpleBean

例子3:

Spring自带的简单支持,例子中完全修改了一个bean的类型,从Dependency类转变为了String类型的字符串。(改变一个bean的类型)


(org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor)

(继承public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor。

这让我们使用这个回调处理适配器来实现能够预测回调处理bean的类型的BeanPostProcessor接口)

我们在下面的定义中指定了一个自动关联的注解,但是我们系统中并没有String类型的dependency关联,只要一个Dependency类交给了Spring。

view
plaincopy
to clipboardprint?

public class SimpleBean
{

@Timestamp

Date creationDate;

@Autowired

String dependency;

@PostConstruct

public void initialize()
{

System.out.println("Initializing
bean " + getClass());

}

@PreDestroy

public void cleanUp()
{

System.out.println("Cleaning
up bean " + getClass());

}

@Override

public String
toString() {

return "Bean
was created at " + this.creationDate
+ " with " + this.dependency;

}

}

我们修改bean的类型:

view
plaincopy
to clipboardprint?

public class TypedDependencyBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
{

public Class
predictBeanType(Class beanClass, String beanName) {

if (beanClass.equals(Dependency.class))
{

return String.class;

}

return beanClass;

}

public Object
postProcessBeforeInitialization(final Object
bean, final String
beanName) throws BeansException
{

if (bean.getClass().equals(Dependency.class))
{

return "Hello,
world";

}

return bean;

}

public Object
postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{

return bean;

}

}

配置:

view
plaincopy
to clipboardprint?

<?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="dependency" class="com.apress.prospring2.ch04.bpp.Dependency"/>

<bean id="simpleBean" class="com.apress.prospring2.ch04.bpp.SimpleBean"/>

<bean id="bpp" class="org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor">

<property name="initAnnotationType" value="javax.annotation.PostConstruct"/>

<property name="destroyAnnotationType" value="javax.annotation.PreDestroy"/>

</bean>

<bean id="bpp2" class="com.apress.prospring2.ch04.bpp.TimestampingBeanPostProcessor"/>

<bean id="bpp3" class="com.apress.prospring2.ch04.bpp.TypedDependencyBeanPostProcessor"/>

<bean id="bpp4" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

</beans>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: