第五章 spring-connet之bean生命周期与bean监控

前言

javaBean

javaBean是java公共组件的标准。起源于Java GUI的可视化编程实现的,所有的组件都需要支持拖拉,那么所有的组件的行为都是一致的。当拖拉组件的时候,就会创建一个改组件的对象,然后进行参数赋值改变组件的属性。 拖拉一个组件等于创建了这个组件的一个对象,在拖拉的时候是无法提供参数的。拖拉之后才能给组件赋值,怎么赋值。

实例化

实例化那么必须是一个类,不是接口,也不能是抽象类

无条件实例化

拖拉完成才能得到真正的坐标,大家不会拖拉之前就设定属性,而是按照原型图,先拖拉在设定属性。所以实例化在前,属性设置在后。如果定义了有参构造函数,那么需要提供参数才能实例化,等于先设定属性,不符合Java GUI的可视化编程中拖拉的规则。组件必须要有一个无参构造方法,可以无条件实例化。

无条件实例化一定有一个无参构造方法,不需要关注其他细节,拉来就可以使用。

变量私有化

其实这个并不是Java GUI的可视化编程里面必须条件,但是因为面向对象设计与面向对象提供封装这个特性,而且变量私有化和封装带来了很多好处,变量私有化成为了javaBean中一个重要的特性

私有化变量通过get/set方法进行操作

当一个组件有很多属性,多个不同属性可以组成一个行为,多个属性出现N中排列组合,是否需要各种排列组合的有参构造方法。

随着时间的推动,需求发生变化,需要添加一个属性,是否出现大量的新的排列组合,需要修改和添加大量的有参构造方法

所以通过get/set的方式,提高了很大的灵活度,扩展度,方便维护

如果某个属性不是提供对外负责,只提供本类或者子类,同包使用,不用与数据传递,可以不提供get/set方法。

总结

Java GUI的可视化编程对组件的定义,对维护,扩展等方面十分友好,很大程度提高了可视化编程效率。等到很多程序员的认可,普及率高,广泛。慢慢成为了javaBean规范。

javaBean规范是整个java体系的基石

javaBean规范是整个java体系的基石

javaBean规范是整个java体系的基石

规范细节

  1. 普通类,才能实例化。不是接口,也不是抽象类
  2. 无参构造方法。如果没有定义无参构造方法,在没有任何其他有参构造方法的情况下,javac会在class文件中生产无参构造方法。这点是Javabean最重要的特性,是不可缺少的。
  3. 变量私有化
  4. 提供变量操作方法get/set, boolean可以使用前缀未is
  5. 变量与方法的命令按照驼峰命名法

public class userInfo{
	
	private long uiId;
	
	private String uiName;
	
	public void setUiId(long uiId){
	 this.uiId = uiId;
	}
	
	public long getUiId(){
		return this.uiId;
	}
	
	public void setUiName(long uiName){
	 this.uiName = uiName;
	}
	
	public long getUiName(){
		return this.uiName;
	}
}

看看这个类


public class niaocai{

	private  int ctl = 1;
	
}

这样也是一个javabean,只是没有set/get。但是因为ctl只是给自己用的

spring的bean

spring的bean其实就参照的ejb的bean,两者从出发点,实现等基本一致,所以占同称bean。已经有了javaBean,为什么还要bean了。在企业需求越来越复杂,造成工程越来越庞大,复杂,脓肿。现有的javabean无法解决问题。所以提出了依赖注入,反转控制的概念。bean是解决依赖注入,反转控制中。

一个框架实现ioc,那么必须提供一个容器,否者无法实现ioc 有容器了,非容器的bean如何想到容器本身的一些bean

看下面有什么问题

public class Niaocai{

	private Niao niao;
	
	private Cai cai;
	
	private String daSshen;
	
	public Niaocai(){
		init();
	}

	public init(){
		if(niao.getxxx == xxxx && cai.getXXXX ==xxxx){
			daSshen = "dashen"
		}else{
			daSshen = "cainiao"
		}
	}

}

上面是不是在实例化的时候会报错。因为调用init比注入要优选。这个问题怎么解决,大家都给下面的解决方案

public class Niaocai{

	private Niao niao;
	
	private Cai cai;
	
	private String daSshen;
	
	public Niaocai(Niao niao , Cai cai){
		this.niao = niao;
		this.cai  = cai;
		if(niao.getxxx == xxxx && cai.getXXXX ==xxxx){
			daSshen = "dashen"
		}else{
			daSshen = "cainiao"
		}
	}
}

解决了在实例化的时候,回答javabean的定义中,分析了构造方法弊端。所以需要另外的解决方法

public class Niaocai{

	private Niao niao;
	
	private Cai cai;
	
	private String daSshen;
	
	@PostConstruct
	public init(){
		if(niao.getxxx == xxxx && cai.getXXXX ==xxxx){
			daSshen = "dashen"
		}else{
			daSshen = "cainiao"
		}
	}
	... get/set方法
}

Niaocai niaocai = new Niaocai();
niaocai.setNaio(niao);
niaocai.setCai(cai);
niaocai.init();

从上面的代码,分析到依赖注入与Aware接口参数注入之后会调用初始化方法。当初始化方法执行完,才标识这个bean完成。实例化完成只是javabean完成的标识。

真确理解bean的生命周期

  1. 实例化
  2. 依赖注入
  3. Aware接口参数注入
  4. 初始化
  5. 销毁

读者会问,bean的生命周期,怎么仅仅有这些啊。不是还有很多接口。 深入了解下什么是生命周期。生命周期是指一个个体的生老病死。那些接口只是对bean进行监控而已。比如单一个生命之前,会进行检测,出生之后会进行户口登记,死亡会注销户口。这些与个人的生命周期没有关系啊。

bean处理体系

bean处理体系是bean最重要的模块之一,本节只是大概,简单让大家了解bean处理系统。在第五章有专门的章节消息的讲述

输入图片说明

@Component
public class NiaoCaiBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor ,MergedBeanDefinitionPostProcessor ,DestructionAwareBeanPostProcessor{

    public NiaoCaiBeanPostProcessor() {
		System.out.println("NiaoCaiBeanPostProcessor ");
    }

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

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

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		// 返回非null,退出链式执行,只会调用beanProcessor.postProcessAfterInitialization方法
		// 当 beanProcessor.postProcessAfterInitialization方法返回非null  会停止接下来的流程。构造调用,依赖注入,初始化等等都不会执行
		System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation   "  +  beanName);
	return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		// 返回false,退出链式执行,会停止依赖注入
		System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation   " +  beanName);
	return true;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,String beanName) throws BeansException {
		System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues   " + beanName+ "   pvs : " + pvs.toString() + " pds : " + pds.toString());
	return pvs;
    }

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		System.out.println("MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition   "  +  beanName);
	
    }

    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		//System.out.println("SmartInstantiationAwareBeanPostProcessor.predictBeanType   " +    beanName);
		return null;
    }

    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
	System.out.println("SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors  "  +  beanName);
	return null;
    }

    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		System.out.println("SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference   "  +  beanName);
	return null;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
		System.out.println("DestructionAwareBeanPostProcessor.postProcessBeforeDestruction  "  +  beanName);
	
    }

    @Override
    public boolean requiresDestruction(Object bean) {
		System.out.println("DestructionAwareBeanPostProcessor.requiresDestruction  " + bean.toString());
	return true;
    }
}

@Comonent
public class ProcessorObject implements InitializingBean , DisposableBean, BeanNameAware{

   // @Autowired
    private Rely rely;
    
    public ProcessorObject() {
	System.out.println("ProcessorObject structure");
    }

    @PostConstruct
    public void postConstruct(){
	System.out.println("javax.annotation.postConstruct  "  + this.getClass().getName());
    }
    
    @PostConstruct
    public void postConstructTwo(){
	System.out.println("javax.annotation.postConstructTwo  "  + this.getClass().getName());
    }
    
    @PreDestroy
    public void preDestroy(){
	System.out.println("javax.annotation.preDestroy  "  + this.getClass().getName());
    }
    
    @Override
    public void destroy() throws Exception {
	System.out.println("DisposableBean destroy  "  + this.getClass().getName());
	
    }

    @Override
    public void afterPropertiesSet() throws Exception {
	System.out.println("InitializingBean.afterPropertiesSet  "  + this.getClass().getName());
    }

    @Override
    public void setBeanName(String name) {
	System.out.println("BeanNameAware : " + name);
	
    }
    
}

public class BeanPostProcessorTest extends SpringContext{
    
    @Test
    public void beanPostProcessorTest(){
	
	this.application.refresh();
	this.application.close();
    }

}

实例化之前

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 执行标志着一个对象生命周期的开始

  1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation processorObject
  2. SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors processorObject

实例化与实例化之后

  1. 执行构造方法,实例化对象 ProcessorObject structure()

  2. 执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition processorObject

  3. 执行MergedBeanDefinitionPostProcessor.postProcessAfterInstantiation 标识对象实例化操作结束 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation processorObject

参数注入 6. InstantiationAwareBeanPostProcessor.postProcessPropertyValues processorObject pvs : PropertyValues: length=0 pds : 参数注入

  1. 基本Awate对象注入,详情请看关于Awate深入解读章节 BeanNameAware : processorObject
初始化
  1. 先执行@PostConstruct javax.annotation.postConstruct com.niaocaia.blog.spring.connet.beanLife.ProcessorObject javax.annotation.postConstructTwo com.niaocaia.blog.spring.connet.beanLife.ProcessorObject

  2. 在执行BeanPostProcessor.postProcessBeforeInitialization BeanPostProcessor.postProcessBeforeInitialization processorObject

  3. 然后执行InitializingBean的afterPropertiesSet InitializingBean.afterPropertiesSet com.niaocaia.blog.spring.connet.beanLife.ProcessorObject

  4. 在执行BeanPostProcessor.postProcessAfterInitialization BeanPostProcessor.postProcessAfterInitialization processorObject

  5. 最后执行DestructionAwareBeanPostProcessor.requiresDestruction , 执行之后,才能使用。 DestructionAwareBeanPostProcessor.requiresDestruction com.niaocaia.blog.spring.connet.beanLife.ProcessorObject@769e7ee8

销毁

先执行执行@preDestroy javax.annotation.preDestroy com.niaocaia.blog.spring.connet.beanLife.ProcessorObject

在执行DestructionAwareBeanPostProcessor 对象的postProcessBeforeDestruction DestructionAwareBeanPostProcessor.postProcessBeforeDestruction processorObject

最后执行 DisposableBean接口的destroy实现方法,整个baen生命周期结束 DisposableBean destroy com.niaocaia.blog.spring.connet.beanLife.ProcessorObject

总结
  1. @PostConstruct与@preDestroy的执行优先DisposableBean与InitializingBean
  2. @PostConstruct在BeanPostProcessor.postProcessBeforeInitialization之前执行,而InitializingBean在BeanPostProcessor.postProcessBeforeInitialization之后执行
  3. @preDestroy在DestructionAwareBeanPostProcessor.postProcessBeforeDestruction之前执行,而DisposableBean在DestructionAwareBeanPostProcessor.postProcessBeforeDestruction之后执行
  4. @PostConstruct与@preDestroy在一个类里面,可以标识在多个方法上。

猜你喜欢

转载自my.oschina.net/u/1261452/blog/1802231