一、什么是对象的生命周期?
指的是一个对象创立、存活、沦亡的一个残缺过程
二、为什么要学习对象的生命周期?
对象的创立在代码层面是简略的,然而从宏观的内存占用的角度上来看,它影响到整个程序的运行,这里就会波及到一些JVM和GC回收机制的问题了总之,由Spring负责对象的创立、存活、销毁,理解生命周期,有利于咱们应用好Spring为咱们创立的对象
三、生命周期的三个阶段
- 创立阶段
3.1 Spring工厂何时创建对象?
scope=“singleton”
当在Spring标签中定义scope的属性为singleton的时候,该bean对象会在Spring工厂创立的同时将bean对象创立起来即当运行了该段代码即会创立=》ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");具体咱们怎么判断呢?咱们能够在类的无参结构中打印一句话来看是否有创立
scope="prototype"
当设置为原型模式的时候,只有当Spring工厂在获取对象的同时才会创建对象即当运行这行代码的时候才会创立=》ctx.getBean("")
留神:只有当创立模式抉择为单例singleton的时候,如果咱们不心愿它追随sprig工厂的创立而创立,那么咱们能够通过bean标签的 lazy-init 属性来进行配置,当该lazy属性为true的时候,那么就只有通过Spring工厂获取对象(即getBean()办法被调用),该对象才会被创立
- 初始化阶段
什么是初始化?艰深点了解就是Spring在创立完bean对象后,还须要做一些动作使得这个bean欠缺起来,具体的内容须要程序员本人去定义,Spring只是提供这个可能性,就犹如父母把你生下来,你还没有欠缺的,须要经验一些货色,才逐步欠缺起来
上面是比拟正式的解释:
在初始化阶段中,Spring工厂在创立完对象后,调用对象的初始化办法,实现对应的初始化操作
1.初始化办法的提供:程序员依据需要提供2.初始化办法调用:Spring工厂进行调用
实现初始化的模式
1> 实现 InitializingBean 接口,重写 afterPropertiesSet() 办法
@Overridepublic void afterPropertiesSet() throws Exception { System.out.println("调用LifeInit初始化办法中........");}
2>本人提供一个一般办法,然而须要在配置文件中本人定义
public class LifeInit{ public LifeInit() { System.out.println("正在创立LifeInit对象"); } //2.自定义初始化办法,在配置文件中配置对应的参数告知spring回调即可 public void myInit(){ System.out.println("(自定义初始化办法)调用LifeInit初始化办法中........"); }}自定义bean标签,并申明init-method参数属性,值为初始化办法的名称<!--自定义初始化办法--><bean id="lifeInit" class="cn.paul.spring.demo.hellospring.life.LifeInit" init-method="myInit"/>
3>*两种模式的比照
实现接口的形式和Spring框架是耦合的关系(因为该接口是Spring提供的),它不便就不便在不须要在配置文件的层面做什么申明,第二种模式就是比拟传统的,然而多做一步就是须要在配置文件中配置对应的属性
4>细节剖析
4.1 如果一个对象不仅实现了InitializingBean接口同时又提供 一般的初始化办法,Spring的调用程序是如何呢?
答复:它会先调用InitializingBean重写的办法,而后再调用自定义的初始化办法这个联合生存教训也很好了解,因为毕竟是用spring嘛
4.2 如果有注入,那么注入是产生在初始化之前还是初始化之后呢?
答复:产生在调用初始化办法之前联合生存教训:有了一些与生俱来的货色,比方五脏六腑,后续能力对人的各方面有所欠缺
4.3 在什么场景会用到初始化操作?
其实在业务编程的角度,用到初始化的机会不多,个别用到的都是一些对于资源的初始化比方:数据库 IO 网络 这些只会做一次的操作(其实这些操作也能够放在注入阶段)
4.4 联合上面的类的代码,说说调用程序是怎么的?
public class LifeInit implements InitializingBean{ private String name; public String getName() { return name; } public void setName(String name) { System.out.println("Spring正在对于LifeBean的name属性进行注入...."); this.name = name; } public LifeInit() { System.out.println("正在创立LifeInit对象"); } //1.重写接口提供的办法让Spring进行接口回调该办法 @Override public void afterPropertiesSet() throws Exception { System.out.println("调用LifeInit初始化办法中........"); } //2.自定义初始化办法,在配置文件中配置对应的参数告知spring回调即可 public void myInit(){ System.out.println("(自定义初始化办法)调用LifeInit初始化办法中........"); }}
下面的代码执行程序为:
①无参结构 =》②set注入 =》③afterPropertiesSet()办法初始化 =》④myInit()自定义办法初始化
- 销毁阶段
Spring销毁对象前,会调用对象的销毁办法,实现销毁操作,留神是【前】
1.Spring什么时候销毁所创立的对象?当咱们调用ctx.close()来敞开工厂的时候,就会对对象进行销毁2.销毁办法谁定义,谁调用?销毁办法是程序员定义的,然而是由Spring来调用的
销毁办法的模式(与初始化办法相似)有哪些?
1.让类实现disposableBean接口
public class LifeInitAndDestroy implements InitializingBean, DisposableBean { private String name; public String getName() { return name; } public void setName(String name) { System.out.println("Spring正在对于LifeBean的name属性进行注入...."); this.name = name; } public LifeInitAndDestroy() { System.out.println("正在创立LifeInit对象"); } //1.重写接口提供的办法让Spring进行接口回调该办法 @Override public void afterPropertiesSet() throws Exception { System.out.println("调用LifeInit初始化办法中........"); } //2.自定义初始化办法,在配置文件中配置对应的参数告知spring回调即可 public void myInit(){ System.out.println("(自定义初始化办法)调用LifeInit初始化办法中........"); } @Override public void destroy() throws Exception { System.out.println("(Spring调用)销毁对象前的操作。。。。"); }}
2.定义一个一般办法,然而在配置文件的标签层面告知Spring这是一个对象销毁的办法
1.在类中定义一般办法public class LifeInitAndDestroy implements InitializingBean, DisposableBean { private String name; public String getName() { return name; } public void setName(String name) { System.out.println("Spring正在对于LifeBean的name属性进行注入...."); this.name = name; } public LifeInitAndDestroy() { System.out.println("正在创立LifeInit对象"); } //1.重写接口提供的办法让Spring进行接口回调该办法 @Override public void afterPropertiesSet() throws Exception { System.out.println("调用LifeInit初始化办法中........"); } //2.自定义初始化办法,在配置文件中配置对应的参数告知spring回调即可 public void myInit(){ System.out.println("(自定义初始化办法)调用LifeInit初始化办法中........"); } @Override public void destroy() throws Exception { System.out.println("(Spring调用)销毁对象前的操作。。。。"); } //3. 自定义销毁办法 public void myDestroy(){ System.out.println("(自定义)销毁对象前的操作。。。。"); }}2.在bean标签中阐明对应的销毁办法<bean id="lifeInit" class="cn.paul.spring.demo.hellospring.life.LifeInitAndDestroy" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="测试初始化bean"/></bean>
阐明: 与初始化阶段相似,初始化阶段是为了实现一些资源的加载,那么销毁阶段就是为了实现一些资源的开释;
- 细节剖析
1.销毁办法的操作只实用于 scope= "singleton",如果为prototype是不调用销毁办法的如果对于初始化办法,不论是singleton还是prototype都是会调用的(记得是ctx.getBean()哦)2.什么时候会用到销毁操作呢?次要波及到一些资源的开释操作,比方:io.close(),connection.close()