Spring4学习回顾之路06- IOC容器中Bean的生命周期方法

Posted DC红茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring4学习回顾之路06- IOC容器中Bean的生命周期方法相关的知识,希望对你有一定的参考价值。

SpringIOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行特定的任务!

Spring IOC容器对Bean的生命周期进行管理的过程:

  -通过构造器或者工厂方法创建Bean实例

  -为Bean的属性设置值和对其他Bean的引用

  -调用Bean的初始化方法

  -Bean可以使用了

  -当容器关闭了,调用Bean的销毁方法

在Bean的声明中设置init-method和destory-method属性,为Bean指定初始化和销毁方法;如图:

  <bean id="student2" class="com.lql.spring03.Student" init-method="init" destroy-method="destory ">
        <property name="name" value="#{‘lql‘}"></property>
        <property name="age" value="#{17}"></property>
   </bean>  

 

当然,除了上述五个过程之外,Bean的生命周期可以更“丰富”点,于是就有了“Bean后置处理器”

Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理;Bean后置处理器对IOC容器里所有的Bean实例逐一处理,而非单一实例。对Bean后置处理器而言,需要实现org.springframework.beans.factory.config.BeanPostProcessor接口,在初始化方法被调用前后,Spring将每个Bean实例分别传递给上述接口的以下两个方法:

 

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

Spring IOC容器对Bean的生命周期进行管理的过程:

  -通过构造器或者工厂方法创建Bean实例

  -为Bean的属性设置值和对其他Bean的引用

  -将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization方法

  -调用Bean的初始化方法

  -将Bean实例传递给Bean后置处理器的postProcessAfterInitialization方法

  -Bean可以使用了

  -当容器关闭了,调用Bean的销毁方法

 案例:建立Bean后置处理器类

package com.lql.spring03;

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

/**
 * @author: lql
 * @date: 2019.10.26
 * Description:
 * Created with IntelliJ IDEA
 */
public class MyBeanPostProcessor implements BeanPostProcessor{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {


        System.out.println("postProcessBeforeInitialization :" + beanName +", " + bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("postProcessAfterInitialization:" + beanName +", " + bean);
        return bean;
    }
}

 

在xml配置文件中配置Bean后置处理器:

  <!--配置bean的后置处理器-->
    <bean class="com.lql.spring03.MyBeanPostProcessor"></bean>

 

 Student.java

package com.lql.spring03;

/**
 * @author: lql
 * @date: 2019.10.12
 * Description:
 * Created with IntelliJ IDEA
 */
public class Student {


    private String name;

    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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


    @Override
    public String toString() {
        return "Student{" +
                "name=‘" + name + ‘‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

 

测试类:

package com.lql.spring03;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author: lql
 * @date: 2019.10.12
 * Description:
 * Created with IntelliJ IDEA
 */
public class Test {


    public static void main(String[] args) {

        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("scope.xml");
        Student student = app.getBean("student", Student.class);
        System.out.println(student);

    }
}

 

输出则显示:

postProcessBeforeInitialization :student, Student{name=‘lql‘, age=17}
postProcessAfterInitialization:student, Student{name=‘lql‘, age=17}
Student{name=‘lql‘, age=17}

 

但是这样有注入危险,比如更改Bean后置处理器的after方法:更改如下:

 @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("postProcessAfterInitialization:" + beanName +", " + bean);
        
        Student student = new Student();
        student.setName("张三");
        return student;
    }

 

这样测试的结果是:

postProcessBeforeInitialization :student, Student{name=‘lql‘, age=17}
postProcessAfterInitialization:student, Student{name=‘lql‘, age=17}
Student{name=‘张三‘, age=0}

 

 

还有个需要注意的是:因为Bean后置处理器是处理所以Bean的,所以可以这么修改:

 @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if ("student".equals(beanName)) {
            //处理步骤
        }
        
        System.out.println("postProcessBeforeInitialization :" + beanName +", " + bean);
        return bean;
    }

 

关于BeanPostProcessor的一些说明:

  -接口,实现用来作用于Bean后置处理器

  -两个方法:Object postProcessBeforeInitialization(Object bean, String beanName):init-method之前被调用

        Object postProcessAfterInitialization(Object bean, String beanName):init-method之后被调用

  参数 bean: bean 实例本身

  参数beanName:IOC容器配置bean的名字

  返回值:是实际上返回给用户的那个Bean,但是可以在上面两个方法中修改返回的bean,甚至返回一个新的bean.

以上是关于Spring4学习回顾之路06- IOC容器中Bean的生命周期方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring4学习回顾之路03—配置Bean (上)

项目一学习框架SpringSecurity08_00_权限控制@Component放到IOC容器里面带盐值的加密

项目一学习框架SpringSecurity08_00_权限控制@Component放到IOC容器里面带盐值的加密

Spring4学习笔记2-配置Bean

Spring4.0学习笔记 —— 自动装配

spring源码学习之路---IOC容器初始化要义之bean定义载入