Spring Bean的生命週期

北冥有隻魚發表於2017-12-18

Instantiate:
Populate properties:依賴注入
BeanNameAwaresetBeanName():
BeanFactoryAware的這個方法可以通過傳入的工廠引數來獲取
BeanPostProcessor的public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException:該方法很酷,它可以做的事情

LifeCycleBean.java
 
package com.lee.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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class LifeCycleBean implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{
	private void info(String infoMsg){
		System.out.println(infoMsg);
	}

	@Override
	public void setBeanName(String arg0) {
		info("步驟三:如果bean實現了BeanNameAware介面,Spring將bean的ID "+arg0+"傳遞給setBeanName方法");
	}
	@Override
	public void setBeanFactory(BeanFactory arg0) throws BeansException {
		info("步驟四:如果bean實現了BeanFactoryAware介面,Spring將呼叫setBeanFactory方法,將BeanFactory容器例項 "+arg0.hashCode()+"傳入進來");
	}
	@Override
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		info("步驟五:如果bean實現了ApplicationContextAware介面,Spring將呼叫setApplicationContext方法,將bean所在的應用上下文引用"+arg0.hashCode()+"傳入進來");
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		info("步驟七:如果bean實現了InitializingBean介面,Spring將呼叫它們的afterPropertiesSet方法。類似地,如果bean使用init-method宣告瞭初始化方法,該方法也會被呼叫");
	}

	@Override
	public void destroy() throws Exception {
		info("步驟十:如果bean實現了DisposableBean介面 ,Spring將呼叫它的destroy介面方法。同樣,如果bean使用destroy-method宣告瞭銷燬方法,該方法也會被呼叫");
	}

}
注意:這裡的BeanFactory例項和ApplicationContext例項不是同一個物件,雖然ApplicationContext繼承了BeanFactory介面,其實實際的情況是ApplicationContext的實現通常包含一個BeanFactory的實現。比如AnnotationConfigApplicationContext就有一個getBeanFactory()方法。

BeanPostProcessImpl.java
package com.lee.pojo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class BeanPostProcessImpl implements BeanPostProcessor {
	private void info(String infoMsg){
		System.out.println(infoMsg);
	}
	@Override
	public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
		info("步驟六:如果有一個公共的bean實現了BeanPostProcessor介面,"
				+ "\n\tSpring將呼叫它們的postProcessBeforeInitialization方法arg0="+arg0+" arg1="+arg1);
		return arg0;
	}

	@Override
	public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
		info("步驟八:如果如果有一個公共的bean實現了BeanPostProcessor介面,"
				+ "\n\tSpring將呼叫它們的postProcessAfterInitialization方法arg0="+arg0+" arg1="+arg1+
				"\n\t這一步該bean就在容器中可以使用了");
		return arg0;
	}
}
注意:BeanPostProcessor的實現一個容器只需要一個,它能幹的事就是,截獲bean被初始(init-method)化前後,可以做一些修改然後返回給容器。



JavaConfig.java
package com.lee.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@ComponentScan(basePackages= {"com.lee"})
public class JavaConfig {

}

M.java
package com.lee;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.lee.config.JavaConfig;

public class TestAnnotation {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext atxt = new AnnotationConfigApplicationContext(JavaConfig.class);
		atxt.close();
	}
}



輸出
步驟三:如果bean實現了BeanNameAware介面,Spring將bean的ID lifeCycleBean傳遞給setBeanName方法
步驟四:如果bean實現了BeanFactoryAware介面,Spring將呼叫setBeanFactory方法,將BeanFactory容器例項 22541646傳入進來
步驟五:如果bean實現了ApplicationContextAware介面,Spring將呼叫setApplicationContext方法,將bean所在的應用上下文引用7125882傳入進來
步驟六:如果有一個公共的bean實現了BeanPostProcessor介面,
	Spring將呼叫它們的postProcessBeforeInitialization方法arg0=com.lee.pojo.LifeCycleBean@4d6e83 arg1=lifeCycleBean
步驟七:如果bean實現了InitializingBean介面,Spring將呼叫它們的afterPropertiesSet方法。類似地,如果bean使用init-method宣告瞭初始化方法,該方法也會被呼叫
步驟八:如果如果有一個公共的bean實現了BeanPostProcessor介面,
	Spring將呼叫它們的postProcessAfterInitialization方法arg0=com.lee.pojo.LifeCycleBean@4d6e83 arg1=lifeCycleBean
	這一步該bean就在容器中可以使用了
一月 01, 2018 11:48:18 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
步驟十:如果bean實現了DisposableBean介面 ,Spring將呼叫它的destroy介面方法。同樣,如果bean使用destroy-method宣告瞭銷燬方法,該方法也會被呼叫




相關文章