zoukankan      html  css  js  c++  java
  • Spring之BeanFactory中Bean的生命周期

    <声明:读书总结自《精通Spring 4.x 企业应用开发实战》 作者:陈雄华 林开雄 文建国>

    spring中bean实例化的过程主要有四个关键点:

    • Bean本身定义的方法,如构造函数,静态代码块,属性设置器等
    • Bean级生命周期控制接口的方法,如BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean
    • 容器级生命周期接口方法,如InstantiationAwareBeanPostProcessorAdapter等后处理器
    • 工厂后处理器接口方法,如:ConfigurationClassPostProcessor等
    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;
    
    /**
     * 这里实现Bean级生命周期控制接口:如BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean
     *
     */
    public class Car implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean{
    
    	private String brand;
    	private String color;
    	private int maxSpeed;
    	
    	private BeanFactory beanFactory;
    	private String beanName;
    	
    	//第二:通过 构造函数,实例化bean,当然 静态代码块在构造之前。
    	static{
    		System.out.println("调用Car的静态代码块");
    	}
    	
    	public Car(){
    		System.out.println("调用Car的构造函数");
    	}
    	
    	public void introduce(){
    		System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
    	}
    	
    	//第五步:对bean的属性进行设置,
    	public void setBrand(String brand){
    		this.brand = brand;
    		System.out.println("调用Car的setBrand()设置属性");
    	}
    	
    	//第十四步:如果实现了DisposableBean接口。容器关闭时会调用销毁方法
    	@Override
    	public void destroy() throws Exception {
    		System.out.println("调用DisposableBean.destroy()");
    	}
    
    	//第十步:如果bean实现了InitializingBean,会调用afterPropertiesSet方法。
    	/*
    	 * This method allows the bean instance to perform initialization only 
    	 * possible when all bean properties have been 
    	 * set and to throw an exception in the event of misconfiguration.
    	 */
    	@Override
    	public void afterPropertiesSet() throws Exception {
    		System.out.println("调用InitializingBean.afterPropertiesSet()");
    	}
    
    	//第六步是:调用  BeanNameAware.setBeanName()的方法,将配置文件中的名称设置到Bean中。
    	@Override
    	public void setBeanName(String beanName) {
    		System.out.println("调用BeanNameAware.setBeanName()");
    		this.beanName = beanName;
    	}
    	
    	//第七:如果bean实现了BeanFactoryAware接口,就会调用此方法,将BeanFactory容器设置到bean中;
    	//BeanFactoryAware接口方法
    	@Override
    	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    		System.out.println("调用BeanFactoryAware.setBeanFactory()");
    		this.beanFactory = beanFactory;
    	}
    	
    	//第十一步:如果配置文件对init-method进行了配置,会调用自定义的init方法
    	public void myInit(){
    		System.out.println("my init()");
    	}
    
    	//第十五步:如果在配置文件中定义了destroy-method="myDestroy",则会调用自定义的销毁方法
    	public void myDestroy(){
    		System.out.println("my derstroy()");
    	}
    
    	public String getColor() {
    		return color;
    	}
    
    	public void setColor(String color) {
    		this.color = color;
    	}
    
    	public int getMaxSpeed() {
    		return maxSpeed;
    	}
    
    	public void setMaxSpeed(int maxSpeed) {
    		this.maxSpeed = maxSpeed;
    	}
    
    	public String getBrand() {
    		return brand;
    	}
    
    	public BeanFactory getBeanFactory() {
    		return beanFactory;
    	}
    
    	public String getBeanName() {
    		return beanName;
    	}
    	
    }
    
    
    import java.beans.PropertyDescriptor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.PropertyValues;
    import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
    
    
    /**
     *@className MyInstantiationAwareBeanPostProcessor
     *@description :容器级 生命周期接口,通过继承InstantiationAwareBeanPostProcessorAdapter适配器来进行扩展。	
     *
     */
    public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
    	
    	/*
    	 * 第一:当 调用者通过getBean("xxx")向spring容器请求该bean,如果容器注册了InstantiationAwareBeanPostProcessorAdapter,
    	 * 会首先吊用此方法,它发生在bean的实例化之前。
    	 */
    	@Override
    	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    		if("car".equals(beanName)){
    			System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()");
    		}
    		return null;
    	}
    
    	/*
    	 * 第三步:如果说  容器注册了InstantiationAwareBeanPostProcessorAdapter,实例化bean之后的首先调用postProcessAfterInstantiation方法;
    	 * 可以在这里对bean实例进行一些改造。
    	 */
    	@Override
    	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    		if("car".equals(beanName)){
    			System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() return boolean");
    		}
    		return true;
    	}
    
    	/*
    	 * 第四步:如果说 bean配置了属性信息, 容器注册了InstantiationAwareBeanPostProcessorAdapter,就会先调用postProcessPropertyValues方法
    	 * 然后才会去调用bean设置属性的相关方法
    	 */
    	@Override
    	public PropertyValues postProcessPropertyValues(
    			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    		if("car".equals(beanName)){
    			System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues() ");
    		}
    		return pvs;
    	}
    
    	/*
    	 * 第九步:通过第八步的BeanPostProcessor的postProcessBeforeInitialization返回到这里的是一个经过特殊处理的bean
    	 * 
    	 * 对于此方法的作用:Apply this BeanPostProcessor to the given new bean instance before any bean initialization 
    	 * callbacks (like InitializingBean's afterPropertiesSet or a custom init-method). 
    	 * The bean will already be populated with property values. 
    	 * The returned bean instance may be a wrapper around the original.
    	 */
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if("car".equals(beanName)){
    			System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() ----");
    		}
    		return bean;
    	}
    
    	/*
    	 * 
    	 * 第十三步:通过第十二步的BeanPostProcessor的postProcessAfterInitialization返回到这里的是一个经过特殊处理的bean
    	 * 
    	 */
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		if("car".equals(beanName)){
    			System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInitialization() ----");
    		}
    		return bean;
    	}
    }
    
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    /**
     *@className MyBeanPostProcessor
     *@description :容器级 生命周期接口,实现	BeanPostProcessor接口;
     *
     *BeanPostProcessor有着重要作用,spring的aop、动态代理就是通过它实施的。
     *
     */
    public class MyBeanPostProcessor implements BeanPostProcessor{
    
    	/*
    	 *
    	 *第八步: 如果BeanFactory装配了BeanPostProcessor后处理器,就会调用postProcessBeforeInitialization方法。这里的参数bean就是
    	 *我们要处理的bean实例。beanName就是当前Bean的配置名,这里进行bean特殊处理。
    	 *
    	 */
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if(beanName.equals("car")){
    			Car car = (Car) bean;
    			if(car.getColor() == null)
    				System.out.println("调用BeanPostProcessor的postProcessBeforeInitialization(),color是空,设置为黑色");
    			car.setColor("黑色");
    		}
    		return bean;
    	}
    
    	/*
    	 *
    	 *第十二步:BeanPostProcessor后处理器的postProcessAfterInitialization,可以继续处理bean实例
    	 *
    	 */
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		if(beanName.equals("car")){
    			Car car = (Car) bean;
    			if(car.getMaxSpeed() > 200)
    				System.out.println("调用BeanPostProcessor的postProcessAfterInitialization(),速度调为200");
    			car.setMaxSpeed(200);
    		}
    		return bean;
    	}
    
    }
    
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    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;
    /**
     * 
     *@className SpringBeanLifeCycle
     *@description :spring bean的生命周期	
     *@date 2017年5月30日下午7:03:13
     *
     *
     * 打印出的结果如下:
     * 	第一步:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
    	第二步:调用Car的静态代码块
    			调用Car的构造函数
    	第三步:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() return boolean
    	第四步:InstantiationAwareBeanPostProcessor.postProcessPropertyValues() 
    	第五步:调用Car的setBrand()设置属性
    	第六步:调用BeanNameAware.setBeanName()
    	第七步:调用BeanFactoryAware.setBeanFactory()
    	第八步:调用BeanPostProcessor的postProcessBeforeInitialization(),color是空,设置为黑色
    	第九步:InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() ----
    	第十步:调用InitializingBean.afterPropertiesSet()
    	第十一步:my init()
    	第十二步:调用BeanPostProcessor的postProcessAfterInitialization(),速度调为200
    	第十三步:InstantiationAwareBeanPostProcessor.postProcessAfterInitialization() ----
    		  brand:奔驰;color:黑色;maxSpeed:200
    	      car1 == car2:true
    	第十四步:调用DisposableBean.destroy()
    	第十五步:my derstroy()
     */
    public class SpringBeanLifeCycle {
    	public static void main(String[] args) {
    		Resource res = new ClassPathResource("spring/IoC/beanlife/applicationContext.xml");
    		BeanFactory bf = new DefaultListableBeanFactory();
    		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) bf);
    		
    		reader.loadBeanDefinitions(res);
    		
    		//在容器中注册 BeanPostProcessor后处理器
    		((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor());
    		
    		//在容器中注册InstantiationAwareBeanPostProcessor后处理器
    		((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
    		
    		//第一次获取Car,会触发容易实例化Bean,调用bean生命周期的方法
    		Car car1 = (Car) bf.getBean("car");
    		car1.introduce();
    		car1.setColor("粉色");
    		
    		//第二次直接从容器缓存池中获取
    		Car car2 = (Car) bf.getBean("car");
    		
    		//所以   这是同一个实例对象。配置文件改为prototype就会不同了。
    		System.out.println("car1 == car2:"+(car1==car2));
    		
    		//关闭容器会 调用destroy方法
    		((ConfigurableBeanFactory)bf).destroySingletons();
    	}
    }
    
    
  • 相关阅读:
    【npm】mac下node环境搭建
    pair求解迷宫的最短路径(bfs)
    dos窗口启动关闭Mysql
    二维差分模板
    一维差分模板
    DOS命令
    迷宫搜索dfs实现
    DFS 迷宫问题
    BFS广搜解决迷宫问题(跟着B站大佬手撸)
    蓝桥杯省赛模拟赛
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608428.html
Copyright © 2011-2022 走看看