Spring中的后置处理器BeanPostProcessor详解

网友投稿 165 2023-06-20

Spring中的后置处理器BeanPostProcessor详解

BeanPostProcessor接口作用:

如果我们想在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的后置处理器PostProcessor配置到Spring配置文件中

xmlns:xsi="http://w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd">

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没有什么太大区别。

2.BeanFactory容器注册bean后置处理器时必须通过代码显示的注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法

void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

Spring如何调用多个BeanPostProcessor实现类:

我们可以在Spring配置文件中添加多个BeanPostProcessor(后置处理器)接口实现类,在默认情况下Spring容器会根据后置处理器的定义顺序来依次调用。

Spring配置文件:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd">

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,

StringUADZW beanName) throws BeansException {

System.ouhttp://t.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 (InterruptedExcUADZWeption 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,优先级最高,值越大优先级越低

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中异或的深入讲解
下一篇:Java文件、文件夹权限修改的两种方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~