Spring提供了一些接口来提供一些方法,体现了bean对象在Spring容器中的生命周期
具体的过程能够体现为:spring
读取权限类名->构建一个类对象->用这个类对象经过无参构造器newInstance()构建对象
↓
调用set方法注入依赖
↓
若是这个Bean已经实现了BeanNameAware接口
调用它实现的setBeanName(String name)方法
此处传递的就是Spring配置文件中Bean的name值
↓
若是这个Bean已经实现了BeanFactoryAware接口
容器会调用它实现的setBeanFactory方法
该方法接收的参数就是当前容器自己(能够用这个方式来获取其它Bean)
↓
若是这个Bean已经实现了ApplicationContextAware接口
容器会调用setApplicationContext方法,该步和第四步相似
↓
若是有类实现了BeanPostProcessor接口而且注入到容器中
那么会执行该类中重写的postProcessBeforeInitialization(Object bean, String beanName)
这个方法在本身定义的init-method以前调用
↓
执行本身在xml配置文件中注入对象定义的init-method方法
↓
若是有类实现了BeanPostProcessor接口而且注入到容器中
那么会执行该类中重写的postProcessAfterInitialization(Object bean, String beanName)
这个方法在本身定义的init-method以后调用
↓
当Bean再也不须要时,会通过清理阶段
若是Bean实现了DisposableBean这个接口
会调用那个其实现的destroy()方法
↓
最后,若是这个Bean的Spring配置中配置了destroy-method属性
会自动调用其配置的销毁方法ide
设计一个类来测试bean对象的生命周期post
/*这里面测试的是spring容器中bean对象完整的生命周期*/ public class Life implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,DisposableBean{ private String name; public String getName() { return name; } //一、容器建立该Bean的对象 public Life() { System.out.println("第一步,建立对象"); } //二、容器给这个Bean对象注入依赖 public void setName(String name) { System.out.println("第二步,依赖注入"); this.name = name; } //三、若是这个Bean已经实现了BeanNameAware接口,容器会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值 @Override public void setBeanName(String name) { System.out.println("第三步,调用setBeanName方法,由于bean类实现了BeanNameAware"); } //四、若是这个Bean已经实现了BeanFactoryAware接口,容器会调用它实现的setBeanFactory方法 //该方法接收的参数就是当前容器自己(能够用这个方式来获取其它Bean) @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("第四步,调用setBeanFactory方法,由于bean类实现了BeanFactoryAware"); } //五、若是这个Bean已经实现了ApplicationContextAware接口,容器会调用setApplicationContext方法,该步和第四步相似,ApplicationContext是BeanFactory的子接口,有更多的实现方法 @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { System.out.println("第五步,调用setApplicationContext方法,由于bean类实现了ApplicationContextAware"); } //九、当Bean再也不须要时,会通过清理阶段,若是Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法; @Override public void destroy() throws Exception { System.out.println("第九步,调用destroy方法,由于bean类实现了ApplicationContextAware"); } /** *注意下面的两个方法是自定义的初始化和销毁对象方法 *须要在注入对象的时候指定init-method="..",destroy-method="..." *注意方法的执行顺序 *init-method在各个初始化方法执行以后才执行 *destroy-method在最后执行 */ //七、若是Bean在Spring配置文件中配置了init-method属性则会自动调用其配置的初始化方法 //init-method="myInit" public void myInit(){ System.out.println("第七步,调用myInit方法,由于bean在xml中的配置里面使用了init-method属性来指定初始化方法"); } //十、最后,若是这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法 public void myDestroy(){ System.out.println("第十步,调用myDestroy方法,由于bean在xml中的配置里面使用了destroy-method属性来指定初始化方法"); } }
再写一个类用来实现BeanPostProcessor接口测试
/*注意:须要把这个类注册到spring的容器中,才能生效*/ public class MyBeanPostProcessor implements BeanPostProcessor{ //这个方法在本身定义的init-method以前调用 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("第六步,调用postProcessBeforeInitialization方法,由于spring容器中注册了BeanPostProcessor接口的实现类"); return bean; } //这个方法在本身定义的init-method以后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("第八步,调用postProcessAfterInitialization方法,由于spring容器中注册了BeanPostProcessor接口的实现类"); return bean; } }
咱们在配置文件中进行一个配置this
<bean class="com.briup.ioc.life.MyBeanPostProcessor"></bean> <bean name="life" class="Life" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="张三"></property> </bean>
以上是完整的生命周期,下面来讲的是非完整的生命周期,通常来讲在开发的时候没有必要每次都让一个对象都具备完整生命周期的方法spa
/*这里面测试的是spring容器中bean对象普通的声明周期*/ /*Bean中不实现spring提供的任何接口,以后项目大多数Bean是这种状况*/ public class LifeBean{ private String name; public LifeBean(){ System.out.println("LifeBean() 构造器"); } public String getName() { return name; } public void setName(String name) { System.out.println("setName() 方法"); this.name = name; } public void init(){ System.out.println("init方法执行"); } public void destory(){ System.out.println("destory方法执行"); } }
生命周器对于单例对象和非单例对象来讲,非单例对象在建立后会脱离容器的控制
单例管理的对象:
1.默认状况下,spring在读取xml文件的时候,就会建立对象
2.进行依赖注入,若是有依赖的话
3.会去调用init-method=".."属性值中所指定的方法,若是有该配置的话
4.Bean对象能够被正常使用
5.对象在被销毁的时候,会调用destroy-method="..."属性值中所指定的方法,若是有该配置的话设计
注意1:调用container.destroy()方法会销毁单例对象
注意2:lazy-init="true",可让这个Bean对象在第一次被访问的时候建立,而不是读取xml文件就被建立
注意3:由于是单例,因此该对象只会被建立一次code
非单例管理的对象:
1.使用这个对象的时候,spring容器会建立这个对象
2.进行依赖注入,若是有依赖的话
3.会去调用init-method=".."属性值中所指定的方法,若是有该配置的话
4.Bean对象能够被正常使用xml
注意1:spring容器不会销毁非单例对象
注意2:由于是非单例,因此每次使用都会建立一个新的Bean对象
非单例也是当获取对象的时候再加载,不会受到Spring容器的管理对象