Spring中bean的生命周期详解(面试说辞)

本文内容纲要:

- Spring中bean生命周期" title="bean的生命周期">bean的生命周期(详解)

- 四个主要阶段

- 常用的扩展点

- 影响多个bean的接口

- 只调用一次的接口

- 与aware有关的接口

- 两个生命周期接口

- 总结:

链接:https://blog.csdn.net/knknknkn8023/article/details/107130806/

Spring中bean的生命周期(详解)

1.四个主要阶段

2.常用的扩展点

3.影响多个bean的接口

4.只调用一次的接口

5.与aware有关的接口

6.两个生命周期接口

7.总结:

四个主要阶段

Spring bean的生命周期只有四个主要阶段,其他都是在这四个主要阶段前后的扩展点,这四个阶段是:

1.实例化 Instantiation

2.属性赋值 Populate

3.初始化 Initialization

4.销毁 Destruction

其中实例化和属性赋值分别对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。

可通过查源码的方式发现,他们都在doCreate()方法中,

// 忽略了无关代码

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

throws BeanCreationException {

// Instantiate the bean.

BeanWrapper instanceWrapper = null;

if (instanceWrapper == null) {

// 实例化阶段!

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

// Initialize the bean instance.

Object exposedObject = bean;

try {

// 属性赋值阶段!

populateBean(beanName, mbd, instanceWrapper);

// 初始化阶段!

exposedObject = initializeBean(beanName, exposedObject, mbd);

}

}

可以发现,分别调用三种方法:

1.createBeanInstance() -> 实例化

2.populateBean() -> 属性赋值

3.initializeBean() -> 初始化

而销毁阶段是在容器关闭时调用的,在ConfigurableApplicationContext类的close()中

常用的扩展点

影响多个bean的接口

两个最重要的接口:

InstantiationAwareBeanPostProcessor

BeanPostProcessor

实现这两个接口的bean,会自动切入到相应的生命周期中,其中InstantiationAwareBeanPostProcessor是作用于实例化阶段的前后,BeanPostProcessor是作用于初始化阶段的前后。

具体代码如图:

package cn.xmx.ioc.lifecycle;

import org.springframework.beans.BeansException;

import org.springframework.beans.PropertyValues;

import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.beans.PropertyDescriptor;

public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {

@Override

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

if(beanName.equals("car")){

System.out.println(beanName+"在实例化之前");

}

return super.postProcessBeforeInstantiation(beanClass, beanName);

}

@Override

public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

if(beanName.equals("car")){

System.out.println(beanName+"在实例化之后");

}

return super.postProcessAfterInstantiation(bean, beanName);

}

}

package cn.xmx.ioc.lifecycle;

import java.lang.reflect.Proxy;

import org.springframework.beans.BeansException;

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

//后置处理器

public class NdBeanPostProcessor implements BeanPostProcessor {

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

System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【前】调用......");

if(beanName.equals("car")) {

return new CglibInterceptor().getIntance(bean.getClass());

}

return bean;

}

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

System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【后】调用......");

return bean;

}

}

package cn.xmx.ioc.lifecycle;

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

import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MainConfig {

@Bean(name="car",initMethod="init",destroyMethod="destroy")

public Car getCar() {

return new Car("大黄蜂");

}

@Bean

public BeanPostProcessor getBeanPostProcessor() {

return new NdBeanPostProcessor();

}

@Bean

public InstantiationAwareBeanPostProcessorAdapter getIns(){

return new MyInstantiationAwareBeanPostProcessorAdapter();

}

}

package cn.xmx.ioc.lifecycle;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/*

四个主生命周期

(1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()

1.实例化

(2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation()

2.填充属性(给属性赋值)

(1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization()

3.初始化化(比如准备资源文件)

3) 属性进行干预 ----修改属性或属性值

(2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization()

4.销毁(释放资源---对象从内存销毁)

N个接口

1、干预多次

1)BeanPostProcessor

2、干预一次

1)Aware

*/

public class TestLifeCycle {

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

Car car = (Car) context.getBean("car");

System.out.println(car);//toString

System.out.println("beanname:"+car.getBeanName());

System.out.println("beanfactory:"+car.getBeanFactory());

System.out.println("applicationContext:"+car.getApplicationContext());

}

}

只调用一次的接口

与aware有关的接口

BeanNameAware

BeanFactoryAware

ApplicationContextAware

需要实体类实现这些接口,分别调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值,调用 setBeanFactory() 方法传入当前工厂实例的引用,调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。

具体代码如下图所示:

package cn.xmx.ioc.lifecycle;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.BeanFactoryAware;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

public class Car implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {

private String name;

private String beanName;

private BeanFactory beanFactory;

private ApplicationContext applicationContext;

public void init() {

System.out.println("car 在初始化---加载资源");

}

public void destroy() {

System.out.println("car 在销毁---释放资源");

}

public Car() {

super();

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Car(String name) {

super();

this.name = name;

System.out.println("car实例化了");

}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

System.out.println("beanFactory:"+beanFactory);

this.beanFactory = beanFactory;

}

public BeanFactory getBeanFactory(){

return this.beanFactory;

}

public void setBeanName(String s) {

System.out.println("beanName:"+s);

this.beanName = s ;

}

public String getBeanName() {

return this.beanName;

}

public ApplicationContext getApplicationContext() {

return this.applicationContext;

}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

System.out.println("applicationContext:"+applicationContext);

this.applicationContext = applicationContext;

}

}

两个生命周期接口

实例化和属性赋值都是Spring帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段。

1.InitializingBean 对应生命周期的初始化阶段,在源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。

2.DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。

总结:

Bean 生命周期的整个执行过程描述如下:

1.如果创建了一个类继承了InstantiationAwareBeanPostProcessorAdapter接口,并在配置文件中配置了该类的注入,即InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessBeforeInstantiation()方法。

2.根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。

3.如果InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessAfterInstantiation()方法。

4.利用依赖注入完成 Bean 中所有属性值的配置注入。

5.如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。

6.如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。

7.如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。

8.如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。

9.如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。

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

11.如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。

注意:以上工作完后才能以后就可以应用这个bean了,那这个bean是一个singleton的,所以一般这种情况下我们调用同一个id的bean会是在内容地址相同的实例,当然在spring配置文件中也可以配置非Singleton。

12.如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

本文内容总结:Spring中bean的生命周期(详解),四个主要阶段,常用的扩展点,影响多个bean的接口,只调用一次的接口,与aware有关的接口,两个生命周期接口,总结:,

原文链接:https://www.cnblogs.com/xushuanglong/p/14632982.html

以上是 Spring中bean的生命周期详解(面试说辞) 的全部内容, 来源链接: utcz.com/z/362444.html

回到顶部