← 返回首页
Spring基础教程(九)
发表时间:2020-05-13 00:43:04
讲解Bean的生命周期

理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。

在@Bean注解中有initMethod和destroyMethod两个属性,其中initMethod属性指定一个方法,在实例化 bean 完成后,立即调用该方法。destroyMethod指定一个方法,只有从容器中移除 bean 时,才能调用该方法。

Bean的生命周期可以表达为:Bean的定义——Bean的setter——Bean的初始化——Bean的使用——Bean的销毁 。

实例

接上一节案例实现。

1.改写Person实体类

package com.entity;


import javax.annotation.Resource;

public class Person {

    private String name;
    private String gender;
    private int age;

    //方式一:@Autowired+@Qualifier
    //@Autowired
    //@Qualifier("car2")

    //方式二:@Resource(name="xxx") 或者属性名字和bean的name保持一致。
    @Resource(name="car2")

    //@Resource
    private Car car;

    public Person() {
        System.out.println("Person Constructor...");
    }

    public Person(String name, String gender, int age) {
        this();
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    //bean的初始化方法
    public void initPerson(){
        System.out.println("initPerson()...");
    }

    //bean的销毁方法
    public void destroyPerson(){
        System.out.println("destroyPerson()...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }


    public void setCar(Car car) {
        System.out.println("setCar(Car car)...");
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", car=" + car +
                '}';
    }
}

2.在SpringConfiguration配置bean.

在@Bean中使用initMethod和destroyMethod定义bean的初始化方法和销毁方法。

package com.config;

import com.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@ComponentScan(basePackages = "com")
public class SpringConfiguration {

    @Bean(name = {"p1","person"},initMethod = "initPerson",destroyMethod = "destroyPerson")
    @Scope("singleton" ) // 注意:作用域必须是singleton,否则bean的销毁方法不执行。
    public Person getPerson(){
        return new Person("zhangsan","男",20);
    }
}

3.测试生命周期

package com.test;

import com.config.SpringConfiguration;
import com.entity.Person;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        Person person = (Person) context.getBean("p1");
        System.out.println(person);
        context.close();//关闭IOC容器
    }
}

运行结果:
Person Constructor...
initPerson()...
Person{name='zhangsan', gender='男', age=20, car=Car{brand='BENZ', color='red'}}
destroyPerson()...

如果Person的bean不是在SpringConfiguration配置中初始化。我们需使用@Component和@PostConstruct以及@PreDestroy实现。代码如下:

package com.entity;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

@Component("p1")
public class Person {
    @Value("zhangsan")
    private String name;
    @Value("男")
    private String gender;
    @Value("20")
    private int age;

    //方式一:@Autowired+@Qualifier
    //@Autowired
    //@Qualifier("car2")

    //方式二:@Resource(name="xxx") 或者属性名字和bean的name保持一致。
    @Resource(name="car2")

    //@Resource
    private Car car;

    public Person() {
        System.out.println("Person Constructor...");
    }

    public Person(String name, String gender, int age) {
        this();
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    //bean的初始化方法
    @PostConstruct
    public void initPerson(){
        System.out.println("initPerson()...");
    }

    //bean的销毁方法
    @PreDestroy
    public void destroyPerson(){
        System.out.println("destroyPerson()...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }


    public void setCar(Car car) {
        System.out.println("setCar(Car car)...");
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", car=" + car +
                '}';
    }
}

如果使用XML配置方式,init-method和destroy-method用法如下:

<bean class="com.entity.Person" name="p1,person" scope="prototype" init-method="initPerson" destroy-method="destroyPerson">
         <property name="name" value="zhangsan"/>
         <property name="gender" value="男"/>
         <property name="age" value="20"/>
         <property name="car" ref="car"/>
</bean>