package com.jd.spring.test.pojo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Person implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public void setBeanFactory(BeanFactory paramBeanFactory)
throws BeansException {
System.out.println("》》》调用了BeanFactoryAware的setBeanFactory方法了");
}
@Override
public void setBeanName(String paramString) {
System.out.println("》》》调用了BeanNameAware的setBeanName方法了");
}
@Override
public void destroy() throws Exception {
System.out.println("》》》调用了DisposableBean的destroy方法了");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("》》》调用了Initailization的afterPropertiesSet方法了");
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex
+ "]";
}
}
package com.jd.spring.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
*实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,
* Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,
* 并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,
* 也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,
* 并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,
在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息,
*/
public class FactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("******调用了BeanFactoryPostProcessor");
String[] beanStr = configurableListableBeanFactory.getBeanDefinitionNames();
for (String beanName : beanStr) {
if ("person".equals(beanName)) {
BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(beanName);
MutablePropertyValues m = beanDefinition.getPropertyValues();
if (m.contains("name")) {
m.addPropertyValue("name", "赵四");
System.out.println("》》》修改了name属性初始值了");
}
}
}
}
}
package com.jd.spring.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
BeanPostProcessor接口:这个接口是单独成类的,它的作用范围是Spring容器,一旦在容器中配置了这个类,那么该容器中所有bean在初始化的前后都会调用这个接口对应的方法
*/
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;
}
}
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 支持Spring注解 -->
<!--<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />-->
<!-- Annotation -->
<context:annotation-config />
<context:component-scan base-package="com.jd" />
<!-- 注册一个BeanPostProcessor -->
<bean id="postProcessor" class="com.jd.spring.test.processor.PostProcessor"/>
<!-- 注册一个BeanFactoryPostProcessor -->
<bean id="factoryPostProcessor" class="com.jd.spring.test.processor.FactoryPostProcessor"/>
<!-- 普通bean -->
<bean id="person" class="com.jd.spring.test.pojo.Person">
<property name="name" value="张三"/>
<property name="sex" value="男"/>
</bean>
</beans>
package com.jd.spring.test;
import com.jd.spring.test.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class T {
public static void main(String[] args) {
System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
ApplicationContext applicationcontext= new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
Person person = (Person) applicationcontext.getBean("person");
System.out.println(person.toString());
System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
}
}
打印结果:
》》》Spring ApplicationContext容器开始初始化了......
七月 17, 2018 10:48:03 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@46f7f36a: startup date [Tue Jul 17 22:48:03 CST 2018]; root of context hierarchy
七月 17, 2018 10:48:03 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
******调用了BeanFactoryPostProcessor
》》》修改了name属性初始值了
/**
* 此处为Spring内部的bean 并没有implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware这些接口
* 所以 只是仅仅走了下BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法
* BeanPostProcessor接口:这个接口是单独成类的,它的作用范围是Spring容器,一旦在容器中配置了这个类,那么该容器中所有bean在初始化的前后都会调用这个接口对应的方法
*/
后置处理器处理bean=【org.springframework.context.event.internalEventListenerProcessor】开始
后置处理器处理bean=【org.springframework.context.event.internalEventListenerProcessor】完毕!
后置处理器处理bean=【org.springframework.context.event.internalEventListenerFactory】开始
后置处理器处理bean=【org.springframework.context.event.internalEventListenerFactory】完毕!
/**
* Person 实现了BeanNameAware接口的打印效果
*/
》》》调用了BeanNameAware的setBeanName方法了
/**
* Person 实现了BeanFactoryAware接口的打印效果
*/
》》》调用了BeanFactoryAware的setBeanFactory方法了
/**
* 注意:这里虽然Person 没有implements BeanPostProcessor接口 但是仍然会执行BeanPostProcessor接口的
* 中的postProcessBeforeInitialization方法
* 因为BeanPostProcessor:bean级别的处理,针对某个具体的bean进行处理 所以每个bean初始化前后 都会走此方法
* BeanPostProcessor接口:这个接口是单独成类的,它的作用范围是Spring容器,一旦在容器中配置了这个类,
* 那么该容器中所有bean在初始化的前后都会调用这个接口对应的方法
*/
后置处理器处理bean=【person】开始
》》》调用了Initailization的afterPropertiesSet方法了
/**
* 注意:这里虽然Person 没有implements BeanPostProcessor接口 但是仍然会执行BeanPostProcessor接口的
* 中的postProcessAfterInitialization方法
* 因为BeanPostProcessor:bean级别的处理,针对某个具体的bean进行处理 所以每个bean初始化前后 都会走此方法
* BeanPostProcessor接口:这个接口是单独成类的,它的作用范围是Spring容器,一旦在容器中配置了这个类,
* 那么该容器中所有bean在初始化的前后都会调用这个接口对应的方法
*/
后置处理器处理bean=【person】完毕!
Person [name=赵四, sex=男]
》》》Spring ApplicationContext容器初始化完毕了......
Process finished with exit code 0