两种后处理器
Bean后处理器:这种后处理器会对容器中的Bean进行后处理,对Bean 进行额外加强。容器后处理器:这种后处理器对IoC容器进行后处理,用于增强容器功能。
Bean后处理器
Bean后处理器,是一种特殊的Bean,它的作用主要是对其他的Bean执行后处理,他会在Bean实例创建完成以后,对其进行进一步的增强管理。它必须实现BeanPostProcessor接口。
实例
目录结构
接口Axe
package service;
public interface Axe {
public String chop();
}
Person
package service;
public interface Person {
public void useAxe();
}
Chinese
package service.impl;
import org.springframework.beans.factory.InitializingBean;
import service.Axe;
import service.Person;
public class Chinese
implements Person, InitializingBean
{
private Axe axe;
private String name;
public Chinese()
{
System.out.println("Spring实例化主调bean:Chinese实例...");
}
public void setAxe(Axe axe)
{
this.axe = axe;
}
public void setName(String name)
{
System.out.println("Spring执行setName()方法注入依赖关系...");
this.name = name;
}
public void useAxe()
{
System.out.println(name + axe.chop());
}
// 下面是两个生命周期方法
public void init()
{
System.out.println("正在执行初始化方法 init...");
}
public void afterPropertiesSet() throws Exception
{
System.out.println("正在执行初始化方法 afterPropertiesSet...");
}
}
SteelAxe
package service.impl;
import service.Axe;
public class SteelAxe
implements Axe
{
public SteelAxe()
{
System.out.println("Spring实例化依赖bean:SteelAxe实例...");
}
public String chop()
{
return "钢斧砍柴真快";
}
}
MyBeanPostProcessor
package util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import service.impl.Chinese;
public class MyBeanPostProcessor
implements BeanPostProcessor
{
/**
* 对容器中的Bean实例进行后处理
* @param bean 需要进行后处理的原Bean实例
* @param beanName 需要进行后处理的Bean的配置id
* @return 返回后处理完成后的Bean
*/
public Object postProcessBeforeInitialization
(Object bean , String beanName)
{
System.out.println("Bean后处理器在初始化之前对"
+ beanName + "进行增强处理...");
// 返回的处理后的Bean实例,该实例就是容器中实际使用的Bean
// 该Bean实例甚至可与原Bean截然不同
return bean;
}
public Object postProcessAfterInitialization
(Object bean , String beanName)
{
System.out.println("Bean后处理器在初始化之后对"
+ beanName + "进行增强处理...");
// 如果该Bean是Chinese类的实例
if (bean instanceof Chinese)
{
// 修改其name成员变量
Chinese c = (Chinese)bean;
c.setName("疯狂iOS讲义");
}
return bean;
}
}
BeanTest
package test;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import service.Person;
public class BeanTest {
public static void main(String[] args)throws Exception
{
// 以类加载路径下的beans.xml文件来创建Spring容器
// ApplicationContext ctx = new
// ClassPathXmlApplicationContext("beans.xml");
// Person p = (Person)ctx.getBean("chinese");
// 搜索类加载路径下的beans.xml文件创建Resource对象
Resource isr = new ClassPathResource("spring-config.xml");
// 创建默认的BeanFactory容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 让默认的BeanFactory容器加载isr对应的XML配置文件
new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(isr);
// 获取容器中的Bean后处理器
BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp");
// 注册Bean后处理器
beanFactory.addBeanPostProcessor(bp);
Person p = (Person)beanFactory.getBean("chinese");
p.useAxe();
}
}
spring-config.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" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置2个普通Bean实例 -->
<bean id="steelAxe" class="service.impl.SteelAxe"/>
<bean id="chinese" class="service.impl.Chinese"
init-method="init" p:axe-ref="steelAxe" p:name="依赖注入的值"/>
<!-- 配置Bean后处理器,可以无需指定id属性 -->
<bean id="bp" class="util.MyBeanPostProcessor"/>
</beans>
运行结果
代码解读
postProcessBeforeInitialization
(Object bean , String beanName)
Object postProcessAfterInitialization
(Object bean , String beanName)
这两个方法为BeanPostProcessor
接口所定义的方法,第一个方法会在Bean初始化之前回调,第二个方法会在Bean初始化之后回调,他们的参数:第一个参数为即将进行后处理的Bean实例,第二个参数为该Bean的配置Id.
容器后处理器
容器后处理器负责对容器本身负责。它必须实现BeanFactoryPostProcessor接口
例子
目录结构
其中红线内的代码没有变!
MyBeanFactoryPostProcessor
package org.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor
implements BeanFactoryPostProcessor
{
/**
* 重写该方法,对Spring容器进行后处理
* @param beanFactory Spring容器本身
*/
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory)
throws BeansException
{
System.out.println("程序对Spring所做的BeanFactory初始化没有改变...");
System.out.println("Spring容器是:" + beanFactory);
}
}
BeanTest
package gao;
import org.service.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest
{
public static void main(String[] args)
{
ApplicationContext ctx = new
ClassPathXmlApplicationContext("beans.xml");
Person p = (Person)ctx.getBean("chinese");
p.useAxe();
}
}
beans.xml
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- 配置两个简单Bean实例 -->
<bean id="steelAxe" class="org.service.impl.SteelAxe"/>
<bean id="chinese" class="org.service.impl.Chinese"
init-method="init" p:name="孙悟空" p:axe-ref="steelAxe"/>
<!-- 配置容器后处理器 -->
<bean id="beanFactoryPostProcessor"
class="org.util.MyBeanFactoryPostProcessor"/>
</beans>
运行结果