欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Bean的生命周期

程序员文章站 2022-07-09 21:01:15
Spring容器可以管理singleton作用域的Bean的生命周期,可以调用创建、初始化、销毁等生命周期的方法。 对于prototype作用域的Bean,Spring容器只负责创建,创建后Bean的实例就交给客户端代码来管理,Spring容器不再跟踪其生命周期。 Bean的生命周期 1、根据配置情 ......

 

spring容器可以管理singleton作用域的bean的生命周期,可以调用创建、初始化、销毁等生命周期的方法。

对于prototype作用域的bean,spring容器只负责创建,创建后bean的实例就交给客户端代码来管理,spring容器不再跟踪其生命周期。

 

 

bean的生命周期

1、根据配置情况,调用bean的构造方法或工厂方法实例化bean

2、利用依赖注入完成bean中所有属性值的配置注入

 

3、如果bean实现了beannameaware接口,则调用setbeanname()方法传入当前bean的id。

4、如果bean实现了beanfactoryaware接口,则调用setbeanfactory()传入当前工厂实例的引用

5、如果bean实现了applicationcontextaware接口,则调用setapplicationcontext()方法传入当前applicationcontext实例的引用

 

6、如果beanpostprocessor和bean关联,则调用预初始化方法postprocessbeforeinitialzation()进行加工操作,spring aop即利用此实现。

 

7、如果bean实现了initializingbean接口,则调用afterpropertiesset()方法

8、如果在配置文件中通过init-method属性指定了初始化方法,则调用初始化方法

 

9、如果beanpostprocessor和bean关联,则调用初始化方法postprocessafterinitialization()。此时,bean已经可以被正常使用了。

 

10、如果指定了作用域为singleton,则将实例放在spring ioc的缓存池中,并触发spring容器对该bean的生命周期管理,如果指定作用域为prototype,则将该bean交给调用者,由调用者管理该bean的生命周期。

 

11、如果bean实现了disposablebean接口,则调用destory()方法销毁实例;

12、如果在配置文件中通过destory-method指定了bean的销毁方法,则调用该方法销毁实例。

 

 

说明:

以上接口中,均只有一个方法。

并不建议让bean实现多个接口,因为继承多个接口会使代码耦合较高。

 

 

 

 

注入依赖后的行为

spring提供2种方式,在bean全部属性设置完成后执行特定的行为:

  • 实现initializingbean接口,在afterpropertiesset()方法中写代码。initializingbean接口中只有这一个方法。
  • 在xml中使用init-method属性指定要调用的方法

可以同时使用这2种方式,会先执行afterpropertiesset(),再执行init-method属性指定的方法。

 

 

 

bean销毁之前的行为

spring提供了2种方式,在bean销毁之前执行特定的行为:

  • 实现disposablebean接口,该接口只有destory()方法
  • 在xml中用destory-method属性指定要调用的方法

可以同时使用这2种方式,会先执行destory(),再执行destory-method属性指定的方法。

 

说明:同时使用时,都是先执行接口中的方法,再执行xml中指定的方法。

 

 

 

示例

 1 class student {
 2     private string name;
 3 
 4     public student(string name){
 5         this.name=name;
 6     }
 7 
 8     public string getname(){
 9         return name;
10     }
11 }
12 
13 class teacher implements initializingbean, disposablebean {
14     @autowired
15     private student student;
16 
17     public void say(){
18         system.out.println(student.getname()+",叫家长来一下");
19     }
20 
21     public void xmlinit(){
22         system.out.println("正在执行xml中init-method属性指定的初始化方法");
23     }
24 
25     @override
26     public void afterpropertiesset() throws exception {
27         system.out.println("正在执行initializingbean接口中的afterpropertiesset()方法");
28     }
29 
30     public void xmldestory(){
31         system.out.println("正在执行xml中destory-method属性指定的方法");
32     }
33 
34     @override
35     public void destroy() throws exception {
36         system.out.println("正在执行disposablebean接口中的destory()方法");
37     }
38 }
39 
40 public class test {
41     public static void main(string[] args) {
42         abstractapplicationcontext applicationcontext=new classpathxmlapplicationcontext("applicationcontext.xml");
43         teacher teacher=applicationcontext.getbean("teacher",teacher.class);
44         teacher.say();
45         applicationcontext.registershutdownhook();
46     }
47 
48 }

在基于web的spring容器中,系统已经提供了相应的代码,在web应用关闭时,会自动关闭spring容器。

在非web的spring的容器中,需要手动调用abstractapplicationcontext类的registershutdownhook()方法向jvm注册一个关闭钩子,执行完前面的代码,会自动关闭spring容器。

applicatiocontext即spring容器。

applicationcontext是接口,没有实现registershutdownhook()方法,abstractapplicationcontext是applicationcontext的子类,实现了该方法,此处要声明为abstractapplicationcontext,不能声明为applicationcontext。

 

 

xml中的配置:

    <context:annotation-config />

    <bean id="student" class="my_package.student">
        <constructor-arg value="张三" />
    </bean>

    <bean id="teacher" class="my_package.teacher" init-method="xmlinit" destroy-method="xmldestory" />

 

 

运行程序,控制台输出如下:

正在执行initializingbean接口中的afterpropertiesset()方法
正在执行xml中init-method属性指定的初始化方法
张三,叫家长来一下
正在执行disposablebean接口中的destory()方法
正在执行xml中destory-method属性指定的方法