学习笔记——Spring(4)bean的生命周期

Spring容器可以管理bean的生命周期。SpringIOC容器对bean的生命周期进行管理的过程:

  1. 通过构造器或工厂方法创建bean实例
  2. 为bean的属性赋值或设置bean的引用
  3. 调用bean的初始化方法(init-method)
  4. bean初始化完成——此时bean可以使用了
  5. 当容器关闭时,调用bean的销毁方法(destroy-method)

 在配置文件中,可以在bean的声明里设置init-method和destroy-method属性,来为bean指定初始化方法和销毁方法。具体实现如下:

实体类:增加初始化方法和销毁方法

package entity;


import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;
import java.util.List;
import java.util.Map;


public class Student extends Person{
    private Integer id;
    private String name;
    private String gender;
    private String liveCountry;
    private Date createTime;
    private Teacher teacher;
    private List<String> subjects;
    private Map<String,Integer> scoreMap;

    public Student(){
        System.out.println("student无参构造");
    }

    public Student(Integer id, String name) {
        System.out.println("student含id、name的构造函数");
        this.id = id;
        this.name = name;
    }

    public Student(Integer id, String name, String gender, String liveCountry) {
        System.out.println("student含id、name、gender、liveCountry的构造函数");
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.liveCountry = liveCountry;
    }

    /**
     * 初始化方法
     */
    public void initStudent(){
        System.out.println("init......");
        this.id = 2;
        this.name = "rose";
    }

    /**
     * 销毁方法
     */
    public void destroyStudent(){
        System.out.println("destroy......");
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    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 String getLiveCountry() {
        return liveCountry;
    }

    public void setLiveCountry(String liveCountry) {
        this.liveCountry = liveCountry;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public List<String> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<String> subjects) {
        this.subjects = subjects;
    }

    public Map<String, Integer> getScoreMap() {
        return scoreMap;
    }

    public void setScoreMap(Map<String, Integer> scoreMap) {
        this.scoreMap = scoreMap;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", liveCountry='" + liveCountry + '\'' +
                ", createTime=" + createTime +
                ", teacher=" + teacher +
                ", subjects=" + subjects +
                ", scoreMap=" + scoreMap +
                '}';
    }
}

配置文件:指定引用的初始化方法和销毁方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="student1" class="entity.Student" init-method="initStudent" destroy-method="destroyStudent">
    </bean>
</beans>

测试类:

package controller;

import entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args){
//        读取配置文件
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
        Student student1 = (Student)ctx.getBean("student1");
        System.out.println(student1);
//        关闭spring容器
        ctx.close();
    }
}

运行结果:

 如果使用注解方式来配置bean,可以结合使用@PostConstruct和@PreDestroy来代替配置文件中的相关配置。具体实现如下:

 配置文件:配置扫描注解

<context:component-scan base-package="entity"></context:component-scan>

实体类代码:

package entity;


import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Repository
@Lazy(value = true)
@Scope("singleton")
public class Student extends Person{
    private Integer id;
    private String name;
    private String gender;
    private String liveCountry;
    private Date createTime;
    private Teacher teacher;
    private List<String> subjects;
    private Map<String,Integer> scoreMap;

    public Student(){
        System.out.println("student无参构造");
    }

    public Student(Integer id, String name) {
        System.out.println("student含id、name的构造函数");
        this.id = id;
        this.name = name;
    }

    public Student(Integer id, String name, String gender, String liveCountry) {
        System.out.println("student含id、name、gender、liveCountry的构造函数");
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.liveCountry = liveCountry;
    }

    /**
     * 初始化方法
     */
    @PostConstruct
    public void initStudent(){
        System.out.println("init......");
        this.id = 2;
        this.name = "rose";
    }

    /**
     * 销毁方法
     */
    @PreDestroy
    public void destroyStudent(){
        System.out.println("destroy......");
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    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 String getLiveCountry() {
        return liveCountry;
    }

    public void setLiveCountry(String liveCountry) {
        this.liveCountry = liveCountry;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public List<String> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<String> subjects) {
        this.subjects = subjects;
    }

    public Map<String, Integer> getScoreMap() {
        return scoreMap;
    }

    public void setScoreMap(Map<String, Integer> scoreMap) {
        this.scoreMap = scoreMap;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", liveCountry='" + liveCountry + '\'' +
                ", createTime=" + createTime +
                ", teacher=" + teacher +
                ", subjects=" + subjects +
                ", scoreMap=" + scoreMap +
                '}';
    }
}

执行测试类,得到相同的结果。

注意:必须确保scope为singleton,否则@PreDestroy修饰的方法不会执行

bean的后置处理器:实际上还可以定制更细粒度的bean生命周期方法,Spring提供了bean的后置处理器,可以在bean的初始化方法前后,对bean进行额外的处理。bean后置处理器是对Spring容器中的所有bean实例进行相同处理,而不是单一的、针对性的。其典型应用是:检查bean属性的正确性或根据特定标准更改bean属性。

bean后置处理器需要实现【org.springframework.beans.factory.config.BeanPostProcessor】接口,重写其中的postProcessBeforeInitialization、postProcessAfterInitialization方法,在初始化方法调用前后,Spring容器会把bean实例通过这两个方法进行处理。加入后置处理器的bean生命周期为:

  1. 通过构造器或工厂方法创建bean实例
  2. 为bean的属性赋值或设置bean的引用
  3. 后置处理器的postProcessBeforeInitialization方法
  4. 调用bean的初始化方法(init-method)
  5. 后置处理器的postProcessAfterInitialization方法
  6. bean初始化完成——此时bean可以使用了
  7. 当容器关闭时,调用bean的销毁方法(destroy-method)

具体实现如下:

创建后置处理器:

package entity;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeanProcessor implements BeanPostProcessor {
    //init-method之前被调用
    @Override
    public Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException{
        System.out.println("postProcessBeforeInitialization...bean:"+var1.toString()+"beanName:"+var2);
        return var1;
    }
    //init-method之后被调用
    @Override
    public Object postProcessAfterInitialization(Object var1, String var2) throws BeansException{
        System.out.println("postProcessAfterInitialization...bean:"+var1.toString()+"beanName:"+var2);
        return var1;
    }
}

配置文件中配置后置处理器:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="student1" class="entity.Student" init-method="initStudent" destroy-method="destroyStudent">
    </bean>
    <!--配置bean的后置处理器:不需要设置id,对所有bean有效-->
    <bean class="entity.BeanProcessor"></bean>
</beans>

测试类:

package controller;

import entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args){
//        读取配置文件
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
        Student student1 = (Student)ctx.getBean("student1");
        System.out.println(student1);
//        关闭spring容器
        ctx.close();
    }
}

运行结果:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值