三、Spring学习 : Bean---->Bean的生命周期+模版设计模式
Bean的生命周期
点击查看本节代码
public class AutowiredBeanPostProcessor {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//我们之前使用的DefaultListableBeanFactory想要加入Bean需要做一个描述类,相比大家还记得第一讲的AbstractBeanDefinition
//要先搞一个描述,然后把描述注册到工厂,beanFactory.registerBeanDefinition();
//我们这里用一个简单的定义方式,这种定义方式会认为你的Bean已经初始化好了
beanFactory.registerSingleton("bean2",new Bean2());
beanFactory.registerSingleton("bean3",new Bean3());
//再来加上一个帮我们解析@Value的自动装配解析器,目前我们知道他可以帮我们解析@Value,其实功能非常强大
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
//再加一个解析${}的解析器
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
//把AutowiredAnnotationBeanPostProcessor单拿出来,让他去作用于Bean1,如果需要找Bean2和Bean3,去beanFactory里面
AutowiredAnnotationBeanPostProcessor BeanPostProcessor =
new AutowiredAnnotationBeanPostProcessor();
BeanPostProcessor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
// System.out.println(bean1);
// //这个Bean后处理器的方法,我们之前是不是学到过呢?在bean的生命周期的依赖注入阶段,我们使用到了的,
// // 第一个参数是我们注入值,第二个是我们处理的Bean,第三个是我们Bean的名称
// BeanPostProcessor.postProcessProperties(null,bean1,"bean1");
// System.out.println(bean1);
//我们看到第一次打印的时候Bean1什么都没有,而第二次打印则自动注入了进去
//那么AutowiredAnnotationBeanPostProcessor到底怎么玩的呢?
//我们先将上面的代码注释,观察底层代码,发现就是先找到加了@Autowired、@Value的成员变量和方法参数然后封装成InjectionMetadata,然后反射调用,注入值
Method method = AutowiredAnnotationBeanPostProcessor.class
.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
method.setAccessible(true);
InjectionMetadata injectionMetadata =
(InjectionMetadata) method.invoke(BeanPostProcessor, "bean1", Bean1.class, null);//获取加了@Autowired、@Value的成员变量和方法参数
System.out.println(injectionMetadata);//断点调试我们看到已经解析了@Autowired、@Value的成员变量和方法参数
injectionMetadata.inject(bean1,"bean1",null);
System.out.println(bean1);
//已经生效
//1.按类型注入成员变脸时:
//如何按照类型注入呢?
Field field = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor dd = new DependencyDescriptor(field,false);//Spring底层会将field封成DependencyDescriptor依赖描述
Object o = beanFactory.doResolveDependency(dd, null, null, null);
System.out.println(o);
//查看打印结果,我们发现已经找到了Bean3并创建
//2.注入方法变量时:
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 =
new DependencyDescriptor(new MethodParameter(setBean2,0),false);
Object o2 = beanFactory.doResolveDependency(dd2, null, null, null);
System.out.println(o2);
//3.值注入的时候,相比已经形成了套路
Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3 =
new DependencyDescriptor(new MethodParameter(setHome,0),false);
Object o3 = beanFactory.doResolveDependency(dd3, null, null, null);
System.out.println(o3);
}
}
package com.itvayne.springbootcloudstudy.spring_03_beanlife;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
public class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
log.debug("@Autowired 生效: {}}", bean2);
this.bean2 = bean2;
}
@Autowired
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
log.debug("@Resource 生效: {}}", bean3);
this.bean3 = bean3;
}
private String port;
@Autowired
public void setHome(@Value("${JAVA_HOME}")String port) {
log.debug("@Value 生效: {}", port);
this.port = port;
}
@PostConstruct
public void init() {
log.debug("@PostConstruct 生效");
}
@PreDestroy
public void destroy() {
log.debug("@PreDestroy 生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", port='" + port + '\'' +
'}';
}
}
public class Bean2 {
}
public class Bean3 {
}
@Component
@ConfigurationProperties(prefix = "java.beanlife")
@PropertySource("classpath:/application.properties")
public class Bean4 {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Bean4{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class BeanPostProcessor {
public static void main(String[] args) {
//准备一个比较干净的容器
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.registerBean("bean1", Bean1.class);
ctx.registerBean("bean2", Bean2.class);
ctx.registerBean("bean3", Bean3.class);
ctx.registerBean("bean4", Bean4.class);
//换一个自动装配候选者解析器,这个后面会详细学习,默认的解析器解析不了String类型
ctx.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
ctx.registerBean(AutowiredAnnotationBeanPostProcessor.class);//@Autowired、@Value 注解的处理器
ctx.registerBean(CommonAnnotationBeanPostProcessor.class);//@Resource @PostConstruct @PreDestroy
//现在运行之后会发现@Autowired、@Value都找到了
ConfigurationPropertiesBindingPostProcessor.register(ctx.getDefaultListableBeanFactory());
ctx.refresh();
System.out.println(ctx.getBean(Bean4.class));
ctx.close();
}
}
@SpringBootApplication
public class LifeApplication {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootCloudStudyApplication.class, args);
applicationContext.close();
}
}
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger (MyBeanPostProcessor.class);
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessBeforeDestruction <<<<销毁前");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + " <<<<postProcessBeforeInstantiation<<<<Bean实例化之前,返回的结果如果不是null,会替换掉原来的Bean");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + " <<<<postProcessAfterInstantiation<<<<Bean实例化之后,返回的是false的话,会直接跳过依赖注入的阶段");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessProperties <<<<依赖注入阶段,比如@Autowired,@Resource,@Value");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessBeforeInitialization <<<<初始化之前,@PostConstruct,@ConfigurationProperty");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessAfterInitialization <<<<初始化之后,代理增强");
}
return bean;
}
}
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory myBeanFactory = new MyBeanFactory();
// myBeanFactory.addBeanPostProcessor(bean -> {
// System.out.println("扩展依赖注入功能");
// return null;
// });
myBeanFactory.getBean();
}
static class MyBeanFactory {
public Object getBean() {
Object object = new Object();
System.out.println("构造:" + object);
System.out.println("依赖注入:" + object);//此时我们认为依赖注入的扩展性可能会很大
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
beanPostProcessor.inject(object);
}
System.out.println("初始化:" + object);
return object;
}
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
beanPostProcessors.add(beanPostProcessor);
}
}
static interface BeanPostProcessor {
public Object inject(Object bean);
}
}
先说结论:
构造 -> 依赖注入-> 初始化方法 -> 容器关闭时,触发销毁方法(单例Bean)

Bean的后处理器提供了Bean的生命周期各个阶段的一个扩展,那么目前有哪些Bean后处理器呢?
先来看两个接口中的后处理器:
InstantiationAwareBeanPostProcessor和DestructionAwareBeanPostProcessor
package com.itvayne.springbootcloudstudy.spring_03_beanlife;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger (MyBeanPostProcessor.class);
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessBeforeDestruction <<<<销毁前");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + " <<<<postProcessBeforeInstantiation<<<<Bean实例化之前,返回的结果如果不是null,会替换掉原来的Bean");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + " <<<<postProcessAfterInstantiation<<<<Bean实例化之后,返回的是false的话,会直接跳过依赖注入的阶段");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessProperties <<<<依赖注入阶段,比如@Autowired,@Resource,@Value");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessBeforeInitialization <<<<初始化之前,@PostConstruct,@ConfigurationProperty");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("beanName = " + beanName + "<<<<postProcessAfterInitialization <<<<初始化之后,代理增强");
}
return bean;
}
}

结合SpringBean的四个生命周期,我们比较典型的后处理器就是上面的六种
模版设计模式
package com.itvayne.springbootcloudstudy.spring_03_beanlife;
import org.springframework.beans.BeansException;
import java.util.ArrayList;
import java.util.List;
/**
* @program: cloud
* @description:
* @author: Vayne
* @create: 2023-12-07
**/
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory myBeanFactory = new MyBeanFactory();
// myBeanFactory.addBeanPostProcessor(bean -> {
// System.out.println("扩展依赖注入功能");
// return null;
// });
myBeanFactory.getBean();
}
static class MyBeanFactory {
public Object getBean() {
Object object = new Object();
System.out.println("构造:" + object);
System.out.println("依赖注入:" + object);//此时我们认为依赖注入的扩展性可能会很大
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
beanPostProcessor.inject(object);
}
System.out.println("初始化:" + object);
return object;
}
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
beanPostProcessors.add(beanPostProcessor);
}
}
static interface BeanPostProcessor {
public Object inject(Object bean);
}
}
这个是比较简单的模版方法,希望初学者能好好体会模版方法的使用
常见的后处理器
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
我们在之前文章中提到过,
public class BeanPostProcessor {
public static void main(String[] args) {
//准备一个比较干净的容器
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.registerBean("bean1", Bean1.class);
ctx.registerBean("bean2", Bean2.class);
ctx.registerBean("bean3", Bean3.class);
//换一个自动装配候选者解析器,这个后面会详细学习,默认的解析器解析不了String类型
ctx.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
ctx.registerBean(AutowiredAnnotationBeanPostProcessor.class);//@Autowired、@Value 注解的处理器
ctx.registerBean(CommonAnnotationBeanPostProcessor.class);//@Resource @PostConstruct @PreDestroy
//现在运行之后会发现@Autowired、@Value都找到了
ctx.refresh();
ctx.close();
}
}
public class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
log.debug("@Autowired 生效: {}}", bean2);
this.bean2 = bean2;
}
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
log.debug("@Resource 生效: {}}", bean3);
this.bean3 = bean3;
}
private String port;
@Autowired
public void setHome(@Value("${JAVA_HOME}")String port) {
log.debug("@Value 生效: {}", port);
this.port = port;
}
@PostConstruct
public void init() {
log.debug("@PostConstruct 生效");
}
@PreDestroy
public void destroy() {
log.debug("@PreDestroy 生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", port='" + port + '\'' +
'}';
}
}
public class Bean2 {
}
public class Bean3 {
}
执行之后会发现这两个处理器的功能和作用,我们这里使用到的容器是GenericApplicationContext,相比于之前的DefaultListableBeanFactory使用更加方便
再来说一个SpringBoot中的一个后处理器,我们常常会用到@ConfigurationProperties注解
//准备一个比较干净的容器
GenericApplicationContext ctx = new GenericApplicationContext();
ctx.registerBean("bean1", Bean1.class);
ctx.registerBean("bean2", Bean2.class);
ctx.registerBean("bean3", Bean3.class);
ctx.registerBean("bean4", Bean4.class);
//换一个自动装配候选者解析器,这个后面会详细学习,默认的解析器解析不了String类型
ConfigurationPropertiesBindingPostProcessor.register(ctx.getDefaultListableBeanFactory());
ctx.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
ctx.registerBean(AutowiredAnnotationBeanPostProcessor.class);//@Autowired、@Value 注解的处理器
ctx.registerBean(CommonAnnotationBeanPostProcessor.class);//@Resource @PostConstruct @PreDestroy
//现在运行之后会发现@Autowired、@Value都找到了
ctx.refresh();
System.out.println(ctx.getBean(Bean4.class));
ctx.close();
ConfigurationPropertiesBindingPostProcessor.register(ctx.getDefaultListableBeanFactory());
ctx.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
对于@ConfigurationProperties注解的后处理器,可以帮我们解析@ConfigurationProperties注解,那么在这里展示的Bean后处理器我们之后会逐一学习
AutowiredAnnotationBeanPostProcessor
我们在上文其实看到了AutowiredAnnotationBeanPostProcessor是来帮我们解析@Autowired、@Value 注解的Bean后处理器
我们现在来细索运行过程:
public class AutowiredBeanPostProcessor {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//我们之前使用的DefaultListableBeanFactory想要加入Bean需要做一个描述类,相比大家还记得第一讲的AbstractBeanDefinition
//要先搞一个描述,然后把描述注册到工厂,beanFactory.registerBeanDefinition();
//我们这里用一个简单的定义方式,这种定义方式会认为你的Bean已经初始化好了
beanFactory.registerSingleton("bean2",new Bean2());
beanFactory.registerSingleton("bean3",new Bean3());
//再来加上一个帮我们解析@Value的自动装配解析器,目前我们知道他可以帮我们解析@Value,其实功能非常强大
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
//把AutowiredAnnotationBeanPostProcessor单拿出来,让他去作用于Bean1,如果需要找Bean2和Bean3,去beanFactory里面
AutowiredAnnotationBeanPostProcessor BeanPostProcessor =
new AutowiredAnnotationBeanPostProcessor();
BeanPostProcessor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
System.out.println(bean1);
//这个Bean后处理器的方法,我们之前是不是学到过呢?在bean的生命周期的依赖注入阶段,我们使用到了的,
// 第一个参数是我们注入值,第二个是我们处理的Bean,第三个是我们Bean的名称
BeanPostProcessor.postProcessProperties(null,bean1,"bean1");
System.out.println(bean1);
//我们看到第一次打印的时候Bean1什么都没有,而第二次打印则自动注入了进去
}
}
我们再来看看他的在依赖注入的时候干了什么事:

先找到所有有@autowired注解的方法,或者属性,交给InjectionMetadata封装起来,然后反射调用进行赋值操作
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//我们之前使用的DefaultListableBeanFactory想要加入Bean需要做一个描述类,相比大家还记得第一讲的AbstractBeanDefinition
//要先搞一个描述,然后把描述注册到工厂,beanFactory.registerBeanDefinition();
//我们这里用一个简单的定义方式,这种定义方式会认为你的Bean已经初始化好了
beanFactory.registerSingleton("bean2",new Bean2());
beanFactory.registerSingleton("bean3",new Bean3());
//再来加上一个帮我们解析@Value的自动装配解析器,目前我们知道他可以帮我们解析@Value,其实功能非常强大
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
//再加一个解析${}的解析器
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
//把AutowiredAnnotationBeanPostProcessor单拿出来,让他去作用于Bean1,如果需要找Bean2和Bean3,去beanFactory里面
AutowiredAnnotationBeanPostProcessor BeanPostProcessor =
new AutowiredAnnotationBeanPostProcessor();
BeanPostProcessor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
// System.out.println(bean1);
// //这个Bean后处理器的方法,我们之前是不是学到过呢?在bean的生命周期的依赖注入阶段,我们使用到了的,
// // 第一个参数是我们注入值,第二个是我们处理的Bean,第三个是我们Bean的名称
// BeanPostProcessor.postProcessProperties(null,bean1,"bean1");
// System.out.println(bean1);
//我们看到第一次打印的时候Bean1什么都没有,而第二次打印则自动注入了进去
//那么AutowiredAnnotationBeanPostProcessor到底怎么玩的呢?
//我们先将上面的代码注释,观察底层代码
Method method = AutowiredAnnotationBeanPostProcessor.class
.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
method.setAccessible(true);
InjectionMetadata injectionMetadata =
(InjectionMetadata) method.invoke(BeanPostProcessor, "bean1", Bean1.class, null);//获取加了@Autowired、@Value的成员变量和方法参数
System.out.println(injectionMetadata);//断点调试我们看到已经解析了@Autowired、@Value的成员变量和方法参数
injectionMetadata.inject(bean1,"bean1",null);
System.out.println(bean1);
//已经生效
那么InjectionMetadata调用inject的时候干了什么呢?
//1.按类型注入成员变脸时:
//如何按照类型注入呢?
Field field = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor dd = new DependencyDescriptor(field,false);//Spring底层会将field封成DependencyDescriptor依赖描述
Object o = beanFactory.doResolveDependency(dd, null, null, null);
System.out.println(o);
//查看打印结果,我们发现已经找到了Bean3并创建
//2.注入方法变量时:
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 =
new DependencyDescriptor(new MethodParameter(setBean2,0),false);
Object o2 = beanFactory.doResolveDependency(dd2, null, null, null);
System.out.println(o2);
//3.值注入的时候,相比已经形成了套路
Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3 =
new DependencyDescriptor(new MethodParameter(setHome,0),false);
Object o3 = beanFactory.doResolveDependency(dd3, null, null, null);
System.out.println(o3);

浙公网安备 33010602011771号