简介
所谓Bean的生命周期,就是一个 Bean 从创建到销毁,所经历的各种方法调用。
一个Bean的生命周期分为四个阶段:
实例化
(Instantiation):Spring容器负责创建Bean的实例,可以通过构造方法或者无参构造方法进行实例化。属性赋值
(populate):Spring容器通过属性注入的方式为Bean的属性赋值,可以通过setter方法或者无参构造方法进行属性赋值。初始化
(Initialization):在初始化阶段,Spring容器会调用Bean的初始化方法(例如InitializingBean接口的afterPropertiesSet() 方法),以确保Bean的正确初始化。销毁
(Destruction):在销毁阶段,Spring容器会调用Bean的销毁方法(例如DisposableBean接口的destroy() 方法),以便在容器关闭时清理资源。
在整个生命周期中,多个增强接口(后置处理器)贯穿了这四个阶段,这些增强接口为开发者提供了更灵活和强大的功能。
整个过程如下:
设计模式——模板方法
上述使用增强接口的处理方式用到了模板方法
这种设计模式。
模板方法:方法中固定不变的步骤不动,会变化的部分(刚开始设计时不可以确定的部分)设计成抽象接口,在特定的时机调用抽象方法。
// 利用模板方法这种设计模式,可以实现在属性注入阶段进行动态扩展
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
beanFactory.getBean();
}
// 模板方法 Template Method Pattern
static class MyBeanFactory {
private final List<BeanPostProcessor> processors = new ArrayList<>();
/**
* 构造、依赖注入、初始化以及销毁这些方法都是固定的保持不动
* 在依赖注入阶段扩展属于会变化的部分,抽象成接口动态添加增强方法
*/
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
// 会变化的部分
for (BeanPostProcessor processor : processors) {
processor.inject(bean);
}
System.out.println("初始化 " + bean);
System.out.println("销毁" + bean);
return bean;
}
// 添加增强接口实现
public void addBeanPostProcessor(BeanPostProcessor processor) {
processors.add(processor);
}
}
/**
* 抽象接口
*/
interface BeanPostProcessor {
// 对依赖注入阶段的扩展
void inject(Object bean);
}
}
自定义BeanPostProcessor
自定义BeanPostProcessor,可以在每个Bean生命周期任意一个阶段执行自定义逻辑
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
// 返回null不会替换
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
// return false;
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy");
}
}
BeanPostProcessor执行顺序
BeanPostProcessor执行顺序可以排序:(无排序按添加顺序执行)
/*
bean 后处理的的排序
*/
public class TestProcessOrder {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加一些后置处理器&排序器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
List<BeanPostProcessor> list = new ArrayList<>();
list.add(new P1());
list.add(new P2());
list.add(new P3());
list.add(new P4());
list.add(new P5());
// bean后置处理器排序 按 order 排序 (order从小到大排序)
list.sort(beanFactory.getDependencyComparator());
list.forEach(processor -> {
processor.postProcessBeforeInitialization(new Object(), "");
});
/*
排序之后:
1. 实现了 PriorityOrdered 接口的优先级最高
2. 实现了 Ordered 接口与加了 @Order 注解的平级, 按数字升序
3. 其它的排在最后
*/
}
@Order(1)
static class P1 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P1.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization @Order(1)");
return bean;
}
}
@Order(2)
static class P2 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P2.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization @Order(2)");
return bean;
}
}
// 优先级最高(排序的话)
static class P3 implements BeanPostProcessor, PriorityOrdered {
private static final Logger log = LoggerFactory.getLogger(P3.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization PriorityOrdered");
return bean;
}
@Override
public int getOrder() {
return 100;
}
}
static class P4 implements BeanPostProcessor, Ordered {
private static final Logger log = LoggerFactory.getLogger(P4.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization Ordered");
return bean;
}
@Override
public int getOrder() {
return 0;
}
}
static class P5 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P5.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization");
return bean;
}
}
}
PostProcessor
BeanFactoryPostProcessor 和 BeanPostProcessor 作用及执行时机
BeanFactoryPostProcessor解析Bean定义
BeanPostProcessor 在初始化Bean阶段进行增强扩展
BeanPostProcessor
用于对象属性赋值
如果不往该容器里添加一些后置处理器的话,将类交给Spring容器管理,获得对象时,对象中的属性一般不会被赋值
添加一些后置处理器:
AutowiredAnnotationBeanPostProcessor
:用于解析@Autowired、@Value
CommonAnnotationBeanPostProcessor
:用于解析@Resource、@PostConstruct、@PreDestroy
ConfigurationPropertiesBindingPostProcessor
:用于解析@ConfigurationProperties,读取配置信息
public class A04 {
public static void main(String[] args) {
// ⬇️GenericApplicationContext 是一个【干净】的容器 【没有添加任何后置处理器】
GenericApplicationContext context = new GenericApplicationContext();
// ⬇️用原始方法注册三个 bean
context.registerBean("bean1", Bean1.class);
context.registerBean("bean2", Bean2.class);
context.registerBean("bean3", Bean3.class);
context.registerBean("bean4", Bean4.class);
// 设置解析器,否则@Value注解会报错
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 解析@Autowired @Value
context.registerBean(CommonAnnotationBeanPostProcessor.class); // @Resource @PostConstruct @PreDestroy
// 解析@ConfigurationProperties(prefix = "java")
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
// ⬇️初始化容器
context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例 (不执行该方法会报错)
System.out.println(context.getBean(Bean1.class));
System.out.println(context.getBean(Bean4.class));
// ⬇️销毁容器
context.close();
/*
学到了什么
a. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能
b. 这些扩展功能由 bean 后处理器来完成
*/
}
}
AutowiredAnnotationBeanPostProcessor 运行分析 (DI依赖注入)
// AutowiredAnnotationBeanPostProcessor 运行分析
public class DigInAutowired {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2", new Bean2()); // 创建过程,依赖注入,初始化
beanFactory.registerSingleton("bean3", new Bean3());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); // @Value
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders); // ${} 的解析器
// 1. 查找哪些属性、方法加了 @Autowired, 这称之为 InjectionMetadata
// AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
// processor.setBeanFactory(beanFactory);
// Bean1 bean1 = new Bean1();
// System.out.println(bean1);
// processor.postProcessProperties(null, bean1, "bean1"); // 执行依赖注入 @Autowired @Value
// System.out.println(bean1);
// 反射调用 findAutowiringMetadata 方法找到类中带有@Autowired、@Value注解的属性信息
// Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
// findAutowiringMetadata.setAccessible(true);
// InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);// 获取 Bean1 上加了 @Value @Autowired 的成员变量,方法参数信息
// System.out.println(metadata);
// 2. 调用 InjectionMetadata 来进行依赖注入, 注入时按类型查找值
// metadata.inject(bean1, "bean1", null);
// System.out.println(bean1);
// 3. 如何按类型查找值 反射通过属性名或者方法名找到属性值
Field bean3 = Bean1.class.getDeclaredField("bean3");
// true找不到属性对象直接报错,false找不到属性对象返回null,然后使用反射将属性对象设置给bean对象
DependencyDescriptor dd1 = new DependencyDescriptor(bean3, false);
Object o = beanFactory.doResolveDependency(dd1, null, null, null);
System.out.println(o);
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 =
new DependencyDescriptor(new MethodParameter(setBean2, 0), true);
Object o1 = beanFactory.doResolveDependency(dd2, null, null, null);
System.out.println(o1);
Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome, 0), true);
Object o2 = beanFactory.doResolveDependency(dd3, null, null, null);
System.out.println(o2);
}
}
BeanFactoryPostProcessor
用于解析Bean定义
ConfigurationClassPostProcessor
:用于解析@ComponentScan、@Bean、@Import、 @ImportResource,将类解析成一个一个bean注册到Spring容器中
MapperScannerConfigurer
:Mybatis自定义后置处理器,相当于@MapperScan,将一个个Mybatis Mapper接口解析成MapperFactoryBean对象注册到BeaFactory容器中
/*
BeanFactory 后处理器的作用
*/
public class A05 {
public static void main(String[] args) throws IOException {
// ⬇️GenericApplicationContext 是一个【干净】的容器
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config", Config.class);
// Spring自带后置处理器
context.registerBean(ConfigurationClassPostProcessor.class); // @ComponentScan @Bean @Import @ImportResource
// 三方自定义后置处理器
context.registerBean(MapperScannerConfigurer.class, bd -> { // @MapperScan
bd.getPropertyValues().add("basePackage", "com.lkl.spring.chapter5.mapper");
});
// ⬇️初始化容器
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
Mapper1 mapper1 = context.getBean(Mapper1.class);
Mapper2 mapper2 = context.getBean(Mapper2.class);
System.out.println("-->" + mapper1);
System.out.println("-->" + mapper2);
// ⬇️销毁容器
context.close();
/*
学到了什么
a. @ComponentScan, @Bean, @Mapper 等注解的解析属于核心容器(即 BeanFactory)的扩展功能
b. 这些扩展功能由不同的 BeanFactory 后处理器来完成, 其实主要就是补充了一些 bean 定义
*/
}
}
Config配置类:
@Configuration
@ComponentScan("com.lkl.spring.chapter5.component")
public class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean(initMethod = "init")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
/* @Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
@Bean
public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory) {
MapperFactoryBean<Mapper2> factory = new MapperFactoryBean<>(Mapper2.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}*/
}
自定义简易PostProcessor,解析@ComponentScan注解
public class ComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override // context.refresh
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
try {
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (componentScan != null) {
for (String p : componentScan.basePackages()) {
System.out.println(p);
// com.lkl.spring.chapter5.component -> classpath*:com/lkl/spring/chapter5/component/**/*.class 文件夹及子文件夹下所有类
String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
System.out.println(path);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// 根据路径寻找资源
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
// System.out.println(resource);
// 解析类的元数据
MetadataReader reader = factory.getMetadataReader(resource);
// System.out.println("类名:" + reader.getClassMetadata().getClassName());
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
// System.out.println("是否加了 @Component:" + annotationMetadata.hasAnnotation(Component.class.getName()));
// System.out.println("是否加了 @Component 派生:" + annotationMetadata.hasMetaAnnotation(Component.class.getName()));
if (annotationMetadata.hasAnnotation(Component.class.getName())
|| annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
// 创建BeanDefinition注册到Spring中
AbstractBeanDefinition bd = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
// 生成beanName
String name = generator.generateBeanName(bd, beanFactory);
beanFactory.registerBeanDefinition(name, bd);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
自定义简易PostProcessor,解析@Bean注解
public class AtBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
try {
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/lkl/spring/chapter5/Config.class"));
Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
System.out.println(method);
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.setFactoryMethodOnBean(method.getMethodName(), "config");
// 设置自动装配的类型 构造器
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
if (initMethod.length() > 0) {
builder.setInitMethodName(initMethod);
}
AbstractBeanDefinition bd = builder.getBeanDefinition();
beanFactory.registerBeanDefinition(method.getMethodName(), bd);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
自定义简易PostProcessor,解析@Mapper注解
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:com/lkl/spring/chapter5/mapper/**/*.class");
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
for (Resource resource : resources) {
MetadataReader reader = factory.getMetadataReader(resource);
ClassMetadata classMetadata = reader.getClassMetadata();
if (classMetadata.isInterface()) {
// 创建 MapperFactoryBean BeanDefinition
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
// 根据 Mapper className 生成 BeanDefinition 从而生成 beanName
AbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
String name = generator.generateBeanName(bd2, beanFactory);
beanFactory.registerBeanDefinition(name, bd);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
注册自定义后置处理器,与上方效果一致
public class A05 {
public static void main(String[] args) throws IOException {
// ⬇️GenericApplicationContext 是一个【干净】的容器
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config", Config.class);
context.registerBean(ComponentScanPostProcessor.class); // 解析 @ComponentScan
context.registerBean(AtBeanPostProcessor.class); // 解析 @Bean
context.registerBean(MapperPostProcessor.class); // 解析 Mapper 接口
// ⬇️初始化容器
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
Mapper1 mapper1 = context.getBean(Mapper1.class);
Mapper2 mapper2 = context.getBean(Mapper2.class);
System.out.println("-->" + mapper1);
System.out.println("-->" + mapper2);
// ⬇️销毁容器
context.close();
/*
学到了什么
自定义后置处理器解析注解,封装为BeanDefinition 注册到Spring容器中
*/
}
}