Spring之Bean的生命周期
- Aware接口
- 项目结构
- 项目代码
- 运行结果
- 源代码
- 使用场景
- InitializingBean接口
- 项目结构
- 项目代码
- 运行结果
- 源代码
- BeanFactoryPostProcessor接口
- 项目结构
- 项目代码
- 运行结果
- 源代码
- Bean的生命周期
- 项目结构
- 项目代码
- 运行结果
- 源代码
Aware接口
实现Aware接口是为了bean能获取某些信息、感知某些信息。Aware自身是一个空的接口,Spring提供了很多它的实现接口,开发者实现这些已有的接口就能获取特定的一些信息。
Spring提供了一些Aware接口的实现接口:
ApplicationContextAware、ApplicationEventPublisherAware、BeanClassLoaderAware、BeanFactoryAware、BeanNameAware、EmbeddedValueResolverAware、EnvironmentAware、ImportAware、LoadTimeWeaverAware、MessageSourceAware、NotificationPublisherAware、ResourceLoaderAware
项目结构
项目代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>spring-bean-life-cycle</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
</dependencies>
</project>
AwareBean.java
package com.spring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author honey
* @date 2023-08-13 16:08:02
*/
public class AwareBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware {
private String beanName;
private ClassLoader classLoader;
private ApplicationContext applicationContext;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public String getBeanName() {
return beanName;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
}
SpringTest01.java
package com.spring.test;
import com.spring.bean.AwareBean;
import org.springframework.context.support.GenericApplicationContext;
/**
* @author honey
* @date 2023-08-13 16:43:37
*/
public class SpringTest01 {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("awareBean", AwareBean.class);
applicationContext.refresh();
AwareBean awareBean = applicationContext.getBean("awareBean", AwareBean.class);
System.out.println("beanName:" + awareBean.getBeanName());
System.out.println("classLoader:" + awareBean.getClassLoader());
System.out.println("applicationContext:" + awareBean.getApplicationContext());
applicationContext.close();
}
}
运行结果
源代码
使用invokeAwareMethods方法处理部分Aware实现接口
AbstractApplicationContext.java
DefaultListableBeanFactory.java
AbstractBeanFactory.java
AbstractAutowireCapableBeanFactory.java
使用Bean对象后置处理器(ApplicationContextAwareProcessor)处理部分Aware实现接口
AbstractApplicationContext.java
从AbstractApplicationContext类的finishBeanFactoryInitialization方法一直进入到AbstractAutowireCapableBeanFactory类的initializeBean方法,具体跳转步骤此处省略,可参照上面的跳转步骤
AbstractAutowireCapableBeanFactory.java
ApplicationContextAwareProcessor.java
使用场景
SpringContextUtils.java
package com.bubble.core.util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
/**
* Spring上下文工具类
*
* @author honey
* @date 2021-09-21 18:27:54
*/
@Component
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static <T> T getBean(String s, Class<T> clazz) {
return context.getBean(s, clazz);
}
public static Boolean containsBean(String s) {
return context.containsBean(s);
}
public static Boolean containsBean(Class<?> clazz) {
String first = clazz.getSimpleName().substring(0, 1).toLowerCase();
String after = clazz.getSimpleName().substring(1);
return context.containsBean(first + after);
}
public static <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
public static void publishEvent(ApplicationEvent event) {
context.publishEvent(event);
}
}
InitializingBean接口
InitializingBean接口为bean对象提供了初始化方法,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
Spring为bean对象提供了三种初始化方式:
1.在bean对象中实现InitializingBean接口;
2.使用@Bean注解注入bean对象时指定initMethod属性;
3.在bean对象的方法上使用@PostConstruct注解;
实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率要高一点,但是init-method方式消除了对spring的依赖。如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
@PostConstruct通过Bean对象后置处理器(CommonAnnotationBeanPostProcessor)实现,InitializingBean和@Bean通过IOC工厂(BeanFactory)实现。
项目结构
项目代码
InitBean.java
package com.spring.bean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
/**
* @author honey
* @date 2023-08-13 18:41:58
*/
public class InitBean implements InitializingBean {
@Override
public void afterPropertiesSet() {
System.out.println("InitBean 调用afterPropertiesSet()");
}
@PostConstruct
public void init(){
System.out.println("InitBean 调用init()");
}
public void initMethod(){
System.out.println("InitBean 调用initMethod()");
}
}
SpringConfig.java
package com.spring.config;
import com.spring.bean.InitBean;
import org.springframework.context.annotation.Bean;
/**
* @author honey
* @date 2023-08-13 18:52:09
*/
public class SpringConfig {
@Bean(initMethod = "initMethod")
public InitBean initBean() {
return new InitBean();
}
}
SpringTest02.java
package com.spring.test;
import com.spring.bean.InitBean;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
/**
* @author honey
* @date 2023-08-13 18:48:22
*/
public class SpringTest02 {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("springConfig", SpringConfig.class);
applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
applicationContext.refresh();
InitBean initBean = applicationContext.getBean("initBean", InitBean.class);
System.out.println("InitBean " + initBean);
applicationContext.close();
}
}
运行结果
源代码
@PostConstruct通过Bean对象后置处理器(CommonAnnotationBeanPostProcessor)实现,底层使用反射技术。
AbstractAutowireCapableBeanFactory.java
CommonAnnotationBeanPostProcessor.java
InitDestroyAnnotationBeanPostProcessor.java
InitializingBean通过IOC工厂(BeanFactory)实现,底层没有使用反射技术。
AbstractAutowireCapableBeanFactory.java
@Bean通过IOC工厂(BeanFactory)实现,底层使用反射技术。
AbstractAutowireCapableBeanFactory.java
BeanFactoryPostProcessor接口
实现BeanFactoryPostProcessor接口,可以在Spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在Spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory。
ConfigurationClassPostProcessor:主要用于处理配置类,使@Bean、@Import、@ComponentScan等注解生效。
项目结构
项目代码
UserBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-14 01:02:08
*/
public class UserBean {
private String name = "Faker";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyBeanFactoryPostProcessor.java
package com.spring.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* @author honey
* @date 2023-08-14 01:00:25
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 修改bean对象的属性值
BeanDefinition userBean = beanFactory.getBeanDefinition("userBean");
userBean.getPropertyValues().addPropertyValue("name", "Honey");
}
}
SpringTest03.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.processor.MyBeanFactoryPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
/**
* @author honey
* @date 2023-08-14 01:04:16
*/
public class SpringTest03 {
public static void main(String[] args) {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("userBean", UserBean.class);
applicationContext.registerBean(MyBeanFactoryPostProcessor.class);
applicationContext.refresh();
UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
System.out.println("userBean name:" + userBean.getName());
applicationContext.close();
}
}
运行结果
源代码
调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法
AbstractApplicationContext.java
PostProcessorRegistrationDelegate.java
修改bean对象的属性值
AbstractApplicationContext.java
具体跳转步骤此处省略
AbstractAutowireCapableBeanFactory.java
Bean的生命周期
Spring bean的生命周期主要包含四个阶段:实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction
Spring bean的生命周期核心代码:AbstractBeanFactory#getBean()
- 实例化Bean对象,执行构造方法;
- 属性赋值,对Bean对象中的属性进行赋值,如在Bean对象中使用@Autowired注解实现依赖注入以及通过BeanFactoryPostProcessor修改Bean对象中的属性值;
- 初始化阶段,执行Bean对象中Aware相关接口的实现方法;
- 初始化阶段,执行BeanPostProcessor#postProcessBeforeInitialization(),在初始化方法之前执行;
- 初始化阶段,执行初始化方法;
- 初始化阶段,执行BeanPostProcessor#postProcessAfterInitialization(),在初始化方法之后执行;
- 销毁Bean对象;
- 实例化Bean对象,当客户向容器请求一个尚未初始化的Bean对象时,或初始化Bean对象的时候需要注入另一个尚末初始化的依赖时,容器就会调用doCreateBean()方法进行实例化,实际上就是通过反射的方式创建出一个bean对象;
- Bean对象的实例创建完成后,接着就是给这个Bean对象进行属性填充,也就是注入这个Bean依赖的其它Bean对象;
- 属性填充完成后,初始化Bean对象,初始化阶段又可以分为几个步骤:
3.1. 执行Bean对象中Aware相关接口的实现方法;
3.2. Spring会检测Bean对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的某些资源。如实现BeanNameAware接口可以获取到BeanName,实现BeanFactoryAware接口可以获取到BeanFactory等等;
3.3. 执行BeanPostProcessor的前置处理方法postProcessBeforeInitialization(),对Bean进行一些自定义的前置处理;
3.4. 判断Bean是否实现了InitializingBean接口,如果实现了则会执行InitializingBean的afterPropertiesSet()进行初始化;
3.5. 执行用户自定义的初始化方法,如init-method等;
3.6. 执行BeanPostProcessor的后置处理方法postProcessAfterInitialization() ,对Bean进行一些自定义的后置处理;- 初始化完成后,Bean对象就成功创建了,之后就可以使用这个Bean对象, 当Bean对象不再需要时,则会进行销毁操作;
4.1. 首先判断Bean对象是否实现了DestructionAwareBeanPostProcessor接口,如果实现了则会执行DestructionAwareBeanPostProcessor后置处理器的销毁回调方法;
4.2. 其次会判断Bean对象是否实现了DisposableBean接口,如果实现了将会调用其实现的destroy()方法;
4.3. 最后判断这个Bean是否配置了dlestroy-method等自定义的销毁方法,如果是则会自动调用其配置的销毁方法;
项目结构
项目代码
AutowireBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-14 01:48:12
*/
public class AutowireBean {
}
LifeCycleBean.java
package com.spring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author honey
* @date 2023-08-14 01:47:44
*/
public class LifeCycleBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
public LifeCycleBean() {
System.out.println("1.执行无参构造方法");
System.out.println("LifeCycleBean 执行LifeCycleBean()");
}
@Autowired
public void setAutowireBean(AutowireBean autowireBean) {
System.out.println("2.设置对象属性");
System.out.println("LifeCycleBean 执行setAutowireBean() autowireBean = " + autowireBean);
}
public void setName(String name) {
System.out.println("2.设置对象属性");
System.out.println("LifeCycleBean 执行setName() name = " + name);
this.name = name;
}
@Override
public void setBeanName(String name) {
System.out.println("3.执行Aware接口中的方法");
System.out.println("LifeCycleBean 执行setBeanName()");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("3.执行Aware接口中的方法");
System.out.println("LifeCycleBean 执行setBeanClassLoader()");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("3.执行Aware接口中的方法");
System.out.println("LifeCycleBean 执行setApplicationContext()");
}
@Override
public void afterPropertiesSet() {
System.out.println("5.执行初始化方法");
System.out.println("LifeCycleBean 执行afterPropertiesSet()");
}
@PostConstruct
public void postConstruct() {
System.out.println("5.执行初始化方法");
System.out.println("LifeCycleBean 执行postConstruct()");
}
public void initMethod() {
System.out.println("5.执行初始化方法");
System.out.println("LifeCycleBean 执行initMethod()");
}
@Override
public void destroy() {
System.out.println("7.执行销毁方法");
System.out.println("LifeCycleBean 执行destroy()");
}
@PreDestroy
public void preDestroy() {
System.out.println("7.执行销毁方法");
System.out.println("LifeCycleBean 执行preDestroy()");
}
public String getName() {
return name;
}
}
LifeCycBeanFactoryPostProcessor.java
package com.spring.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* @author honey
* @date 2023-08-14 02:13:45
*/
public class LifeCycBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 修改bean对象的属性值
BeanDefinition userBean = beanFactory.getBeanDefinition("lifeCycleBean");
userBean.getPropertyValues().addPropertyValue("name", "Honey");
}
}
LifeCycleBeanPostProcessor.java
package com.spring.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author honey
* @date 2023-08-14 02:01:57
*/
public class LifeCycleBeanPostProcessor implements BeanPostProcessor {
private final String beanName = "lifeCycleBean";
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (this.beanName.equals(beanName)) {
System.out.println("4.bean对象后置处理器初始化方法之前执行");
System.out.println("LifeCycleBean 执行postProcessBeforeInitialization()");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.beanName.equals(beanName)) {
System.out.println("6.bean对象后置处理器初始化方法之后执行");
System.out.println("LifeCycleBean 执行postProcessAfterInitialization()");
}
return bean;
}
}
SpringConfig02.java
package com.spring.config;
import com.spring.bean.AutowireBean;
import com.spring.bean.LifeCycleBean;
import com.spring.processor.LifeCycBeanFactoryPostProcessor;
import com.spring.processor.LifeCycleBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
/**
* @author honey
* @date 2023-08-14 02:17:17
*/
@Import({LifeCycBeanFactoryPostProcessor.class, LifeCycleBeanPostProcessor.class})
public class SpringConfig02 {
@Bean(initMethod = "initMethod")
public LifeCycleBean lifeCycleBean() {
return new LifeCycleBean();
}
@Bean
public AutowireBean autowireBean() {
return new AutowireBean();
}
}
SpringTest04.java
package com.spring.test;
import com.spring.bean.LifeCycleBean;
import com.spring.config.SpringConfig02;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author honey
* @date 2023-08-14 02:15:22
*/
public class SpringTest04 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
LifeCycleBean lifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class);
System.out.println("-----------------------------------");
System.out.println("LifeCycleBean " + lifeCycleBean);
System.out.println("-----------------------------------");
applicationContext.close();
}
}
运行结果
源代码
AbstractBeanFactory.java
AbstractAutowireCapableBeanFactory.java