版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/andy_zhang2007/article/details/84794772
项目简介
- 基于
springboot 2.1.1
- 使用
maven
管理项目 - 非
web
项目
源代码
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>tut</groupId>
<artifactId>zero</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
配置文件 application.yml
threshold: 1000
主程序类
package tut.zero;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
MyBean bean;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
bean.serve();
}
}
用于观察bean生命周期方法调用顺序而自定义的bean
package tut.zero;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 一个为了演示bean生命周期方法调用顺序而专门设计的bean,没有任何实际的业务意义
*/
@Component // 该注解让该类作为一个bean定义被容器发现
public class MyBean implements InitializingBean, DisposableBean, BeanNameAware, BeanClassLoaderAware,
BeanFactoryAware, ApplicationContextAware {
/**
* 构造函数,响应 Java new 操作符
*/
public MyBean() {
System.out.println("1.bean构造阶段 - 1.新建对象 - 构造函数被调用");
}
/**
* 和方法 setThreshold() 配合演示一个配置属性的注入,初始值设置为 null
* 如果使用时为 null,表明带注解 @Value 的方法 setThreshold() 未被调用
*/
Integer threshold = null;
@Value("${threshold}")
public void setThreshold(int threshold) {
System.out.println("1.bean构造阶段 - 2.填充属性 - bean属性注入方法被调用 - @Value setThreshold()");
this.threshold = threshold;
}
/**
* @param environment
*/
@Autowired
public void setEnvironment(Environment environment) {
System.out.println("1.bean构造阶段 - 2.填充属性 - bean依赖注入方法被调用 - @Autowired setEnvironment()");
this.environment = environment;
}
/**
* 和方法 setEnvironment() 配合演示一个 bean 的注入,初始值设置为 null
* 如果使用时为 null,表明带注解 @Autowired 的方法 setEnvironment() 未被调用
*/
Environment environment;
/**
* JSR-250 定义的初始化机会
*/
@PostConstruct
public void postConstruct() {
// 这里观察依赖注入和属性设置是否已经完成
final boolean dependentBeanResolved = this.environment != null;
final boolean dependentPropertyResolved = this.threshold != null;
System.out.printf(
"1.bean构造阶段 - 3.初始化 - JSR-250 @PostConstruct - " +
"@Autowired注解bean已设置 : %s ,@Value注入属性已设置 : %s \n",
dependentBeanResolved,
dependentPropertyResolved
);
}
/**
* InitializingBean接口定义的初始化机会
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("1.bean构造阶段 - 3.初始化 " +
"- InitializingBean#afterPropertiesSet");
}
/**
* 模拟一个该bean组件提供的业务方法,
* 1. 这些业务方法可以有多个
* 2. 每个这样的方法由开发人员根据业务逻辑定义决定如何调用
* 3. 这些方法的调用应该发生在bean被创建和初始化过程结束之后,销毁阶段开始之前
* 4. 对于一般的单例bean,首次注入过程视为该bean创建和初始化过程,将程序结束时容器销毁的过程看作bean进入销毁阶段,
* 换句话讲,当你通过依赖注入方式拿到一个bean实例之后,这个bean实例的创建和初始化过程已经由容器完成,可以用于
* 调用这些业务方法了。bean的销毁也是在程序进入结束流程时由容器完成的,开发人员有机会在bean销毁时做一些事情,
* 但一般来说业务开发人员并不需要太关注bean的销毁流程。
*/
public void serve() {
System.out.println("2.bean服务阶段 - 业务方法被调用");
}
/**
* JSR-250 定义的析构机会
*/
@PreDestroy
public void preDestroy() {
System.out.println("3.bean销毁阶段 - 1.JSR-250 @PreDestroy");
}
/**
* DisposableBean 接口定义的析构机会
*
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("3.bean销毁阶段 - 2.DisposableBean#destroy");
}
/**
* BeanNameAware 接口要求的方法
*
* @param name
*/
public void setBeanName(String name) {
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"Aware 接口方法调用 - BeanNameAware#setBeanName\n");
}
/**
* BeanClassLoaderAware 接口要求的方法
*
* @param classLoader
*/
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"Aware 接口方法调用 - BeanClassLoaderAware#setBeanClassLoader\n");
}
/**
* BeanFactoryAware 接口要求的方法
*
* @param beanFactory
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"Aware 接口方法调用 - BeanFactoryAware#setBeanFactory\n");
}
/**
* ApplicationContextAware 接口要求的方法
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"Aware 接口方法调用 - ApplicationContextAware#setApplicationContext\n");
}
}
用于观察bean生命周期方法调用顺序而自定义的BeanPostProcessor
package tut.zero;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 针对bean定义 MyBean 设计的一个 BeanPostProcessor 实现,没有任何业务意义,
* 只是用来配合演示 bean 生命周期方法调用的顺序
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean)
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"MyBeanPostProcessor#postProcessBeforeInitialization('%s')\n", beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean)
System.out.printf("1.bean构造阶段 - 3.初始化 - " +
"MyBeanPostProcessor#postProcessAfterInitialization('%s')\n", beanName);
return bean;
}
}
bean生命周期方法调用顺序
1.bean构造阶段 - 1.新建对象 - 构造函数被调用
1.bean构造阶段 - 2.填充属性 - bean属性注入方法被调用 - @Value setThreshold()
1.bean构造阶段 - 2.填充属性 - bean依赖注入方法被调用 - @Autowired setEnvironment()
1.bean构造阶段 - 3.初始化 - Aware 接口方法调用 - BeanNameAware#setBeanName
1.bean构造阶段 - 3.初始化 - Aware 接口方法调用 - BeanClassLoaderAware#setBeanClassLoader
1.bean构造阶段 - 3.初始化 - Aware 接口方法调用 - BeanFactoryAware#setBeanFactory
1.bean构造阶段 - 3.初始化 - Aware 接口方法调用 - ApplicationContextAware#setApplicationContext
1.bean构造阶段 - 3.初始化 - MyBeanPostProcessor#postProcessBeforeInitialization('myBean')
1.bean构造阶段 - 3.初始化 - JSR-250 @PostConstruct - @Autowired注解bean已设置 : true ,@Value注入属性已设置 : true
1.bean构造阶段 - 3.初始化 - InitializingBean#afterPropertiesSet
1.bean构造阶段 - 3.初始化 - MyBeanPostProcessor#postProcessAfterInitialization('myBean')
2.bean服务阶段 - 业务方法被调用
3.bean销毁阶段 - 1.JSR-250 @PreDestroy
3.bean销毁阶段 - 2.DisposableBean#destroy