关于后端:六对象的生命周期

5次阅读

共计 4416 个字符,预计需要花费 12 分钟才能阅读完成。

一、什么是对象的生命周期?

指的是一个对象创立、存活、沦亡的一个残缺过程

二、为什么要学习对象的生命周期?

对象的创立在代码层面是简略的,然而从宏观的内存占用的角度上来看,它影响到整个
程序的运行,这里就会波及到一些 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() 办法

@Override
public 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()
正文完
 0