java

位置:IT落伍者 >> java >> 浏览文章

Spring攻略:创建Bean后处理器


发布日期:2023年10月15日
 
Spring攻略:创建Bean后处理器

知识点

Bean后处理器允许在初始化回调方法前后进行额外的Bean处理Bean后处理器的主要特性是逐个处理IoC容器中的所有Bean实例而不只是单个Bean实例一般来说Bean后处理器用于检查Bean属性的有效性或根据特定条件修改Bean属性

Bean后处理器的基本要求是实现BeanPostProcessor接口通过实现postProcessBeforeInitialization() 和 postProcessAfterInitialization() 方法可以在初始化回调方法前后处理所有BeanSpring将在调用初始化回调方法前后向这两个方法传递每个Bean实例步骤如下

()构造函数或者工厂方法创建Bean实例

()为Bean属性设值和Bean引用

()调用感知接口中定义的设值方法

()将Bean实例传递给每个Bean后处理器中的postProcessBeforeInitialization()方法

()调用初始化回调方法

()将Bean实例传递给每个Bean后处理器中的postProcessAfterInitialization()方法

()Bean准备就绪可以使用

()容器关闭时调用销毁回调函数

使用Bean工厂作为IoC容器时Bean后处理器只能编程注册即通过addBeanPostProcessor方法注册如果使用应用程序上下文只需要在Bean配置文件中声明一个处理器实例它就会自动注册

代码示例

StorageConfig标记接口

[java]

package deprojectjackiespringrecipesnotespringadvancedioc;

/**

* 标记接口让Bean后处理器区分应检查的Bean

* @author jackie

*

*/

public interface StorageConfig {

public String getPath();

}

package deprojectjackiespringrecipesnotespringadvancedioc;

/**

* 标记接口让Bean后处理器区分应检查的Bean

* @author jackie

*

*/

public interface StorageConfig {

public String getPath();

} Cashier类

[java]

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioBufferedWriter;

import javaioFile;

import javaioFileWriter;

import javaioIOException;

import javautilDate;

import orgspringframeworkbeansfactoryBeanNameAware;

/**

* Cashier类实现BeanNameAware感知接口和StorageConfig标记接口

* @author jackie

*

*/

public class Cashier implements BeanNameAware StorageConfig {

private String name;

private BufferedWriter writer;

private String path;

public void setPath(String path) {

thispath = path;

}

public void openFile() throws IOException {

File file = new File(path name + txt);

FileWriter fw = new FileWriter(file true);

writer = new BufferedWriter(fw);

}

public void checkout(ShoppingCart cart) throws IOException {

double total = ;

for (Product product : cartgetItems()) {

total += productgetPrice();

}

writerwrite(new Date() + \t + total + \r\n);

writerflush();

}

public void closeFile() throws IOException {

writerclose();

}

@Override

public String getPath() {

return path;

}

@Override

public void setBeanName(String beanName) {

thisname = beanName;

}

}

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioBufferedWriter;

import javaioFile;

import javaioFileWriter;

import javaioIOException;

import javautilDate;

import orgspringframeworkbeansfactoryBeanNameAware;

/**

* Cashier类实现BeanNameAware感知接口和StorageConfig标记接口

* @author jackie

*

*/

public class Cashier implements BeanNameAware StorageConfig {

private String name;

private BufferedWriter writer;

private String path;

public void setPath(String path) {

thispath = path;

}

public void openFile() throws IOException {

File file = new File(path name + txt);

FileWriter fw = new FileWriter(file true);

writer = new BufferedWriter(fw);

}

public void checkout(ShoppingCart cart) throws IOException {

double total = ;

for (Product product : cartgetItems()) {

total += productgetPrice();

}

writerwrite(new Date() + \t + total + \r\n);

writerflush();

}

public void closeFile() throws IOException {

writerclose();

}

@Override

public String getPath() {

return path;

}

@Override

public void setBeanName(String beanName) {

thisname = beanName;

}

}

PathCheckingBeanPostProcessor自定义Bean后处理器

[java]

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioFile;

import orgspringframeworkbeansBeansException;

import orgspringframewonfigBeanPostProcessor;

/**

* 通用的组件确保文件在打开之前存在

* @author jackie

*

*/

public class PathCheckingBeanPostProcessor implements BeanPostProcessor {

/**

* 在文件打开之前进行路径检查

* 须返回所处理的Bean的一个实例

*/

@Override

public Object postProcessBeforeInitialization(Object bean String beanName)

throws BeansException {

// 如果Bean实现了StorageConfig接口检查路径是否存在

if (bean instanceof StorageConfig) {

String path = ((StorageConfig)bean)getPath();

File file = new File(path);

if (!fileexists()) {

filemkdirs();

}

}

return bean;

}

/**

* 即使什么都不做也必须返回原来的Bean实例

*/

@Override

public Object postProcessAfterInitialization(Object bean String beanName)

throws BeansException {

return bean;

}

}

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioFile;

import orgspringframeworkbeansBeansException;

import orgspringframewonfigBeanPostProcessor;

/**

* 通用的组件确保文件在打开之前存在

* @author jackie

*

*/

public class PathCheckingBeanPostProcessor implements BeanPostProcessor {

/**

* 在文件打开之前进行路径检查

* 须返回所处理的Bean的一个实例

*/

@Override

public Object postProcessBeforeInitialization(Object bean String beanName)

throws BeansException {

// 如果Bean实现了StorageConfig接口检查路径是否存在

if (bean instanceof StorageConfig) {

String path = ((StorageConfig)bean)getPath();

File file = new File(path);

if (!fileexists()) {

filemkdirs();

}

}

return bean;

}

/**

* 即使什么都不做也必须返回原来的Bean实例

*/

@Override

public Object postProcessAfterInitialization(Object bean String beanName)

throws BeansException {

return bean;

}

}Bean配置

[html]

<?xml version= encoding=UTF?>

<beans xmlns=

xmlns:xsi=instance

xsi:schemaLocation= beansxsd>

<! 注册Bean后处理器 >

<bean class=deprojectjackiespringrecipesnotespringadvancediocPathCheckingBeanPostProcessor />

<bean id=aaa class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=AAA />

<property name=price value= />

</bean>

<bean id=cdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=CDRW />

<property name=price value= />

</bean>

<bean id=dvdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=DVDRW />

<property name=price value= />

</bean>

<bean id=shoppingCart class=deprojectjackiespringrecipesnotespringadvancediocShoppingCart scope=prototype />

<bean id=cashier class=deprojectjackiespringrecipesnotespringadvancediocCashier initmethod=openFile destroymethod=closeFile >

<property name=path value=c:/cashier />

</bean>

</beans>

<?xml version= encoding=UTF?>

<beans xmlns=

xmlns:xsi=instance

xsi:schemaLocation= beansxsd>

<! 注册Bean后处理器 >

<bean class=deprojectjackiespringrecipesnotespringadvancediocPathCheckingBeanPostProcessor />

<bean id=aaa class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=AAA />

<property name=price value= />

</bean>

<bean id=cdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=CDRW />

<property name=price value= />

</bean>

<bean id=dvdrw class=deprojectjackiespringrecipesnotespringadvancediocBattery>

<property name=name value=DVDRW />

<property name=price value= />

</bean>

<bean id=shoppingCart class=deprojectjackiespringrecipesnotespringadvancediocShoppingCart scope=prototype />

<bean id=cashier class=deprojectjackiespringrecipesnotespringadvancediocCashier initmethod=openFile destroymethod=closeFile >

<property name=path value=c:/cashier />

</bean>

</beans>测试类

[java]

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioIOException;

import orgjunitTest;

import orgntextApplicationContext;

import orgntextsupportClassPathXmlApplicationContext;

/**

* @author jackie

*

*/

public class BeanPostProcessorTest {

@Test

public void testBeanPostProcessor() throws IOException {

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(applicationContextxml);

Product aaa = (Product) applicationContextgetBean(aaa);

Product cdrw = (Product) applicationContextgetBean(cdrw);

Product dvdrw = (Product) applicationContextgetBean(dvdrw);

ShoppingCart shoppingCart = (ShoppingCart) applicationContextgetBean(shoppingCart);

shoppingCartaddItem(aaa);

shoppingCartaddItem(cdrw);

shoppingCartaddItem(dvdrw);

Cashier cashier = (Cashier) applicationContextgetBean(cashier);

cashiercheckout(shoppingCart);

}

}

package deprojectjackiespringrecipesnotespringadvancedioc;

import javaioIOException;

import orgjunitTest;

import orgntextApplicationContext;

import orgntextsupportClassPathXmlApplicationContext;

/**

* @author jackie

*

*/

public class BeanPostProcessorTest {

@Test

public void testBeanPostProcessor() throws IOException {

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(applicationContextxml);

Product aaa = (Product) applicationContextgetBean(aaa);

Product cdrw = (Product) applicationContextgetBean(cdrw);

Product dvdrw = (Product) applicationContextgetBean(dvdrw);

ShoppingCart shoppingCart = (ShoppingCart) applicationContextgetBean(shoppingCart);

shoppingCartaddItem(aaa);

shoppingCartaddItem(cdrw);

shoppingCartaddItem(dvdrw);

Cashier cashier = (Cashier) applicationContextgetBean(cashier);

cashiercheckout(shoppingCart);

}

}

书上说如果使用JSR注解@PostConstruct和@PreDestroy并且一个CommonAnnotationBeanPostProcessor实例调用初始化方法那么PathCheckingBeanPostProcessor不能正常工作因为它的默认优先级低于CommonAnnotationBeanPostProcessor经我实践证明PathCheckingBeanPostProcessor仍然可以正常工作

               

上一篇:Struts2 -- s:if标签的使用

下一篇:Java程序性能优化--让你的Java程序更快、更稳定