先说IoC
容器【包含着实例】 <--注入--> 应用程序
Bean就是一系列被容器控制Java对象
“野生”Bean
自行实例化,自行销毁
普通的Java Bean生命周期就是:
实例化 不再被使用时GC
就像自然界的动物,悄然而生,悄然而亡
Spring Bean
对于Spring IoC中的Bean,生命周期可以分为以下阶段
实例化》属性赋值》初始化》程序中使用》销毁
就像人的一生
出生》登记》生长》工作》死亡
Bean的来源
BeanFactory:相当于原始的社会体系
ApllicationContext:相当于现代化的社会体系
Spring Bean详细生命周期
Spring Bean初始化
Aware相关接口处理
BeanPostProcessor前置处理
是否实现InitailizingBean接口(afterPropertiesSet)
是否自定义init-method
BeanPostProcessor后置处理
Spring Bean生命周期类过程
Aware接口:获取社会资源
后处理器:各类手续和证件
生命周期接口:个人选择
配置生命周期方法:主观能动
一:获取社会资源/Aware接口:Aware接口的作用是让Bean能拿到容器的一些资源,例如BeanNameAware可以拿到BeanName。就好像上学之前,要取一个学名——以前很多人上学之前不知道自己大名叫什么,是吧?铁蛋,是吧?大宝,是吧?小宝。
二:必备各种手续和证/后处理器:在Bean的生命周期里,会有一些后处理器,它们的作用就是进行一些前置和后置的处理,就像上学之前,需要登记学籍,上学之后,会拿到毕业证。
三:个人选择/生命周期接口:人可能无法选择如何出生,但也许可以选择如何活着和如何死去,InitializingBean和DisposableBean 接口就是用来定义初始化方法和销毁方法的。
四:主观能动/配置生命周期方法:环境影响人,人也在影响环境,成长的时候认真努力,衰亡的时候也可以豁达乐观。可以通过配置文件,自定义初始化和销毁方法。
用代码来熟悉一下上述流程
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(nameGenerator = NameGenerator.class)
public class LifeCycleApplication {
public static void main(String[] args) {
SpringApplication.run(LifeCycleApplication.class, args);
}
}
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
public class NameGenerator extends AnnotationBeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
String beanName = definition.getBeanClassName();
if (beanName.contains("DaBaoBean")) {
System.out.println("母亲知道自己怀孕了");
beanName = "保国";
System.out.println("母亲和父亲商量孩子出生后叫:" + beanName + ",希望他能保家卫国");
}
return beanName;
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class DaBaoBean implements InitializingBean, BeanFactoryAware, BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, EnvironmentAware, ResourceLoaderAware, MessageSourceAware {
private String beanName;
public DaBaoBean() {
System.out.println("孩子出生了,乳名叫:大宝");
}
@Override
public void setBeanName(String s) {
System.out.println("孩子的身份证姓名叫:" + s);
beanName = s;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("父母给孩子" + beanName + "讲他的出生");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("父母给孩子" + beanName + "选了学校:" + beanFactory.getClass().getSimpleName());
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("父母教孩子" + beanName + "熟悉环境");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("父母教孩子" + beanName + "认识亲朋");
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("父母教孩子" + beanName + "学习沟通");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("父母教孩子" + beanName + "了解人际关系");
}
@PostConstruct
private void init() {
System.out.println("孩子" + beanName + "课余时间努力自学");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("孩子" + beanName + "各项课程学习结束");
}
}
import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class ParentPostProcessor implements BeanPostProcessor, BeanFactoryPostProcessor, InstantiationAwareBeanPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("父母是鸡娃型父母,孩子还没出现先看了周边的教育资源");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("孩子出生前进行产前护理");
}
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("孩子出生后进行产后护理");
}
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("父母办理出院手续");
}
return InstantiationAwareBeanPostProcessor.super.postProcessPropertyValues(pvs, pds, bean, beanName);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("孩子" + beanName + "入学开始九年义务教育");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("孩子" + beanName + "毕业结束九年义务教育");
}
return bean;
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(2)
public class TeachPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("保国".equals(beanName)) {
System.out.println("父母家中富裕,给孩子" + beanName + "继续深造");
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
运行结果
母亲知道自己怀孕了
母亲和父亲商量孩子出生后叫:保国,希望他能保家卫国
父母是鸡娃型父母,孩子还没出现先看了周边的教育资源
孩子出生前进行产前护理
孩子出生了,乳名叫:大宝
孩子出生后进行产后护理
父母办理出院手续
孩子的身份证姓名叫:保国
父母给孩子保国讲他的出生
父母给孩子保国选了学校:DefaultListableBeanFactory
父母教孩子保国熟悉环境
父母教孩子保国认识亲朋
父母教孩子保国学习沟通
父母教孩子保国了解人际关系
孩子保国入学开始九年义务教育
孩子保国课余时间努力自学
孩子保国各项课程学习结束
孩子保国毕业结束九年义务教育
父母家中富裕,给孩子保国继续深造