spring BeanPostProcessor InitializingBean相关

<pre name="code" class="java">public static void main(String[] args) throws Exception {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		TestAware test = (TestAware) ac.getBean("testAware");
	}

	public void testBean() {
		BeanFactory fb = new XmlBeanFactory(new ClassPathResource(
				"applicationContext.xml"));
		TestAware test = (TestAware) fb.getBean("testAware");
	}

package com.test.springmvc.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class TestAware implements ApplicationContextAware, BeanPostProcessor,
		InitializingBean {

	private static ApplicationContext applicationContext;

	private String name = "11";

	public void test() {
		MainTest mainTest = (MainTest) applicationContext.getBean("mainTest");
		// mainTest.test();
	}

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		TestAware.applicationContext = applicationContext;

	}

	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("postProcessBeforeInitialization:" + beanName);
		return null;
	}

	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("postProcessAfterInitialization:" + beanName);
		return null;
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("afterPropertiesSet:");

	}
}
上面的2中方法去初始化bean有什么区别呢?
运行发现,2种都可以实例化bean,但是第二种方法实例化的bean中,applicationContext没有被注入;那这二种方法的区别是什么呢?

<pre name="code" class="html">谁调用了我的postProcessBefore(或After)Initialization()方法
要想知道postProcessBeforeInitialization()和postProcessAfterInitialization()这两个方法在spring中是如和被调用的,或者可是说成是什么时候才会去调用的,那首先我们就要清楚的了解Bean的生命周期。
那在spring中bean的生命周期究竟是怎样的呢
1. 容器寻找Bean的定义信息并将其实例化
2. 使用依赖注入,spring按照Bean定义信息配置Bean的所有属性
3. 如果Bean实现了BeanNameAware接口,工厂调用Bean的SetBeanName()方法传递Bean的ID
4. 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
5. 如果BeanPostProcessor和Bean关联,那么其postProcessBeforeInitialization()方法将被调用
6. 如果Bean指定了init-method方法,将被调用
7. 最后,如果有BeanPostProcessor和Bean关联,那么其postProcessAfterInitialization()方法将被调用
此时,Bean已经可以被应用系统使用,并将被保留在BeanFactory中知道他不再被需要。有两种可以将其从BeanFactory中删除掉的方法
① 如果Bean实现了DisposableBean接口,destroy()方法将被调用
② 如指定了定制的销毁方法,就调用这个方法


 


 
<span style="font-family: Arial, Helvetica, sans-serif;">applicationContext.xml</span>
<bean id="teacherService" class="cn.csdn.cyclelife.TeacherService"  init-method="init" destroy-method="destroy">
 <constructor-arg type="java.lang.Integer" index="0">
 <value>20</value>
  </constructor-arg>
 <property name="name">
 <value>Longmanfei</value>
 </property>
 </bean>
<bean id="postService"class="cn.csdn.cyclelife.PostService"></bean>
//TeacherService bean
public class TeacherService {

    private String name;
 
    private Integer age;
	
	
	public void setName(String name){
		System.out.println("----这是teacherservice的set方法----");
		this.name=name;
	}
	
	public TeacherService(Integer age){
		this.age=age;
	}
	

	public void init(){
		System.out.println("--------这是teacherservice的init的方法-------------");
	}
	
	public void destroy(){
		System.out.println("---------这是销毁(destroy)方法----------");
	}
	
	public void display(){
		System.out.println(this.name+"-----------------"+this.age);
	}
 }
// 实现接口的BeanPostProcessor bean 
 public class PostService implements BeanPostProcessor{

	
	/**在初始化之后调用这个方法*/
	@Override
	public Object postProcessAfterInitialization(Object bean, String arg1)
			throws BeansException {
		System.out.println("----这是init之后执行的方法postProcessAfterInitialization----");
		return bean;
	}

	/**在初始bean之前调用的这个方法 在init方法之前执行,在set方法之后*/
	@Override
	public Object postProcessBeforeInitialization(Object bean, String arg1)
			throws BeansException {
		/**instanceof 判断前者是否是后者的一个实例*/
		if(bean instanceof TeacherService){
			System.out.println("--这是在init之前进行修改bean的属性值--");
			/*这里我们不能直接new一个对象 因为bean本身就是一个对象,直接转换就可以了*/
			((TeacherService)bean).setName("Longmanfei");
		}
	    System.out.println("---这是init之前执行的方法postProcessBeforeInitialization---");
		return bean;
	}
}
//Junit 测试方法
public class App {
	
	
	@Test
	public void test1(){
		/**加载容器*/
		ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applic*.xml"});
		/**调用getbean方法*/
		TeacherService ts = (TeacherService) ac.getBean("teacherService");
		
		
		ts.display();
		
		/**调用close方法关闭bean*/
		AbstractApplicationContext aac =(AbstractApplicationContext) ac;
		aac.close();
	}

}
//这是执行结果(当加载容器的时候会判断是否有实现接口的BeanPostProcessor bean,如果有其他Bean就会按照特定的顺序去执行,并且执行实现接口的bean里的方法)
----这是teacherservice的set方法----
--这是在init之前进行修改bean的属性值--
----这是teacherservice的set方法----
---这是init之前执行的方法postProcessBeforeInitialization---
--------这是teacherservice的init的方法-------------
----这是init之后执行的方法postProcessAfterInitialization----
Longmanfei-----------------20
---------这是销毁(destroy)方法----------

 

<!--EndFragment-->

<!--EndFragment-->



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,您说得对。下面是一个示例代码,用于演示BeanPostProcessorpostProcessAfterInitialization方法在InitializingBean的afterPropertiesSet方法之后执行的情况: ```java import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.stereotype.Component; @Component public class DemoBean implements InitializingBean, BeanPostProcessor { @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean's afterPropertiesSet method called"); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor's postProcessAfterInitialization method called for bean " + beanName); return bean; } public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(DemoBean.class); context.refresh(); DemoBean demoBean = context.getBean(DemoBean.class); } } ``` 在上面的示例中,DemoBean实现InitializingBean接口,并且重写了afterPropertiesSet方法。同时,DemoBean还实现BeanPostProcessor接口,并重写了postProcessAfterInitialization方法。 在程序执行期间,当DemoBean被创建并初始化时,Spring容器会先调用InitializingBean的afterPropertiesSet方法,然后再调用BeanPostProcessorpostProcessAfterInitialization方法。因此,上面的示例代码的输出应该是: ``` InitializingBean's afterPropertiesSet method called BeanPostProcessor's postProcessAfterInitialization method called for bean demoBean ``` 这样,就证明了BeanPostProcessorpostProcessAfterInitialization方法确实是在InitializingBean的afterPropertiesSet方法之后执行的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值