Spring3.2—— BeanPostProcessor、BeanFactoryPostProcessor

 1、Bean后处理器(BeanPostProcessor)

 Bean后处理器,负责对容器中所有的Bean进行某种特定的修改,从而使这批Bean全部获得某种新功能。

Object postProcessBeforeInitialization(Object bean, String beanName):初始化之前执行。

Object postProcessAfterInitialization(Object bean, String beanName):初始化之后执行。

这两个方法形参和返回值:

- bean:即将接受后处理的Bean

- beanName:即将接受被后处理的bean的id。

- 返回值:进行后处理后的Bean。程序既可对该Bean进行修改,也可以替换掉原来Bean、甚至返回null。
步骤:
  a.实现一个Bean处理器。实现BeanPostProcessor接口
  b.将Bean后处理器配置在Spring容器中,Spring容器一旦检测到某个Bean实现了BeanPostProcessor接口,

     Spring就会自动将该Bean注册成容器中的Bean后处理器。

bean的生命周期:

创建实例→注入依赖关系(setter)→BeanNameAware接口中的方法→ApplicationContextAware接口中的方法→初始化前的后处理

→调用afterPropertiesSet→调用init-method→初始化后的后处理→运行阶段→调用destroy→调用destory-method

(1)Bean后处理器使用

eg:

①MyBeanPostProcessor.java

public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
	
		System.out.println("-----初始化之后的后处理-----");
		return bean;
	}
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("-----初始化之前的后处理-----");
		if(bean.getClass() == User.class){
			Field f;
			try {
				f = bean.getClass().getDeclaredField("name");
				f.setAccessible(true);
				f.set(bean,"自定义前缀 "+f.get(bean));
			} catch (Exception e) {				
				e.printStackTrace();
			}
		}
		return bean;
	}
}
②beans.xml

<bean class="cony.domain.MyBeanPostProcessor"/>
<bean id="user" class="cony.domain.User"
p:name="小米"
p:age="4"
/>
<bean id="user2" class="cony.domain.User"
p:name="小明"
p:age="4"
/>
③测试:

		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		User user = ctx.getBean("user",User.class);
		User user2 = ctx.getBean("user2",User.class);
		System.out.println(user);
		System.out.println(user2);
测试结果:


问:Bean后处理器执行几次? 答:由执行结果看出有多少个Bean,它就会执行多少次。

2、容器后处理器(BeanFactoryPostProcessor)

负责对容器进行后处理,从而对Spring容器进行修改、增强。

- postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory):参数代表了将要被后处理的容器。

 只能修改Spring容器,不能替换,更不能将容器替换成null。
     步骤:
      a.实现一个Bean处理器。实现BeanFactoryPostProcessor接口
      b.将Bean后处理器配置在Spring容器中,Spring容器一旦检测到某个Bean实现了BeanFactoryPostProcessor接口,

            Spring就会自动将该Bean注册成容器中的容器后处理器。

(1)容器后处理器使用

eg1:

①MyBeanFactoryPostProcessor.java

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
			throws BeansException {
		
		System.out.println("执行对容器的后处理");
	}
}
②beans.xml

<bean class="cony.domain.MyBeanPostProcessor"/>

<bean class="cony.domain.MyBeanFactoryPostProcessor"/>
<bean id="user" class="cony.domain.User"
p:name="小米"
p:age="4"
/>
③测试

		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		User user = ctx.getBean("user",User.class);
		System.out.println(user);
测试结果:


(2)需要将配置文件中某些信息提取到专门的属性文件中配置管理(比如配置数据库),可以使用下面两个容器后处理器去加载属性文件。
i.PropertyPlaceholderConfigurer:1、先加载配置文件,2、再通过${key}来引用配置文件中的value。

ii.PropertyOverrideConfigurer: 直接在属性文件中配置即可。

eg2:

_平常获取数据库连接

①beans.xml:


②测试:

		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		DataSource source = ctx.getBean("dataSource",DataSource.class);
		System.out.println(source.getConnection());
测试结果:


坏处:属性值改变时需要打开代码修改,所以一般放在属性文件中配置。

_使用PropertyPlaceholderConfigurer

①properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名
user=用户名
password=密码
maxSize=200
minSize=2
initSize=2
②beans.xml

将属性文件放在类路径下,所以用classpath进行加载


其中加载配置文件的代码可以简化为如下:


注:需要导入命名空间


_使用PropertyOverrideConfigurer:

①beans.xml:


②properties文件:需要特定格式


猜你喜欢

转载自blog.csdn.net/ack_finding/article/details/78870893
今日推荐