1. Spring Bean生命周期各个阶段
首先编写一个Bean:
@Component
public class LifeCycleBean {
public LifeCycleBean(){
System.out.println("Bean 构造");
}
@Autowired
public void autowire(@Value("${JAVA_HOME}")String javaHome){
System.out.println("Bean 依赖注入:"+javaHome);
}
@PostConstruct
public void init(){
System.out.println("Bean 初始化");
}
@PreDestroy
public void destroy(){
System.out.println("Bean 被销毁");
}
}
编写主方法测试代码:
@SpringBootApplication
public class A03Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(A03Application.class, args);
context.close();
}
}
Bean 构造
Bean 依赖注入:/opt/development_tools/jdk21/jdk-21.0.3
Bean 初始化
2024-06-08T17:06:10.657+08:00 INFO 30992 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 9000 (http) with context path ''
2024-06-08T17:06:10.672+08:00 INFO 30992 --- [ main] com.cherry.a03.A03Application : Started A03Application in 2.645 seconds (process running for 3.334)
Bean 被销毁
我们发现。完整的Bean生命周期是:
- 通过构造方法实例化Bean对象
- 对Bean对象进行依赖注入(该Bean 可能会引入其它的Bean对象)
- 对Bean对象进行初始化
- Bean对象随着容器的销毁而销毁(当然是在容器销毁前而销毁)
由于默认的而BeanFactory对于Bean管理只有核心的功能,而对Bean功能的怎增强则是通过Bean后处理器来完成的,我破门可以使用不同的Bean后处理器针对Bean不同的生命周期进行扩展。这里举一个简单的例子:
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
System.out.println("<<<销毁之前执行 如 @PreDestroy<<<");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
System.out.println("<<<实例化之前执行,这里返回的对象会替换掉原来的bean <<<");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
System.out.println("<<<实例化之后执行,这里返回false会跳过依赖注入 <<<");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
System.out.println("<<<依赖注入阶段执行,如@Autowired, @AValue, @Resource <<<");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
System.out.println("<<<初始化Bean之前执行,这里返回的对象会替换掉原来的Bean对象,如@POsrConstruct, @ConfigurationProperties <<<");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
System.out.println("<<< 初始化之后执行,这里返回的对象会替换掉原来的Bean,如代理增强<<<");
}
return bean;
}
}
运行:
<<<实例化之前执行,这里返回的对象会替换掉原来的bean <<<
Bean 构造
<<<实例化之后执行,这里返回false会跳过依赖注入 <<<
<<<依赖注入阶段执行,如@Autowired, @AValue, @Resource <<<
Bean 依赖注入:/opt/development_tools/jdk21/jdk-21.0.3
<<<初始化Bean之前执行,这里返回的对象会替换掉原来的Bean对象,如@POsrConstruct, @ConfigurationProperties <<<
Bean 初始化
<<< 初始化之后执行,这里返回的对象会替换掉原来的Bean,如代理增强<<<
2024-06-08T17:31:34.698+08:00 INFO 31600 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 9000 (http) with context path ''
2024-06-08T17:31:34.713+08:00 INFO 31600 --- [ main] com.cherry.a03.A03Application : Started A03Application in 2.913 seconds (process running for 3.471)
<<<销毁之前执行 如 @PreDestroy<<<
Bean 被销毁
2. 模板设计模式
模板设计模式就是在不改变原有代码的基础上,提高现有代码的扩展能力。
模拟Spring容器编写一个BeanFactory
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public void inject(Object bean) {
System.out.println("解析 @Autowired");
}
});
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public void inject(Object bean) {
System.out.println("解析 @Resource");
}
});
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public void inject(Object bean) {
System.out.println("解析 @Value");
}
});
beanFactory.getBean();
}
static class MyBeanFactory{
public Object getBean(){
Object bean = new Object();
System.out.println("构造: "+bean);
System.out.println("依赖注入: "+bean); //@Autowired注解解析
for(BeanPostProcessor processor:processors){
processor.inject(bean);
}
System.out.println("初始化: "+bean);
return bean;
}
// 存储bean后处理器
private List<BeanPostProcessor> processors = new ArrayList<>();
// 想后处理器集合中添加后处理器
public void addBeanPostProcessor(BeanPostProcessor processor){
processors.add(processor);
}
}
static interface BeanPostProcessor{
public void inject(Object bean); // 对依赖注入阶段的功能进行扩展
}
}
构造: java.lang.Object@5f184fc6
依赖注入: java.lang.Object@5f184fc6
解析 @Autowired
解析 @Resource
解析 @Value
初始化: java.lang.Object@5f184fc6
Process finished with exit code 0
将不确定的逻辑操作抽象成接口,将来在特定的时机调用来调用抽象方法。
3. 常见的Bean后处理器
首先定义几个Bean对象:
Bean1:
public class Bean1 {
private Bean2 bean2;
private Bean3 bean3;
private String home;
@Autowired
public void setBean2(Bean2 bean2){
System.out.println("@Autowired 生效:"+bean2);
this.bean2 = bean2;
}
@Resource
public void setBean3(Bean3 bean3){
System.out.println("@Autowired 生效:"+bean3);
this.bean3 = bean3;
}
@Autowired
public void setHome(@Value("${JAVA_HOME}")String home){
System.out.println("@Value 生效:"+home);
this.home = home;
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct 生效");
}
@PreDestroy
public void destroy(){
System.out.println("@PreDestroy 生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", home='" + home + '\'' +
'}';
}
}
Bean2:
public class Bean2 {}
Bean3:
public class Bean3 {}
Bean4:
/**
*java.home=
* java.version=
*/
@ConfigurationProperties(prefix = "java")
public class Bean4 {
private String home;
private String version;
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public String toString() {
return "Bean4{" +
"home='" + home + '\'' +
", version='" + version + '\'' +
'}';
}
}
主程序:
@SpringBootApplication
public class A04Application {
public static void main(String[] args) {
// GenericApplicationContext是一个比较容器,它并没有添加额外的bean处理器
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);
// 添加一个解析@Autowired和@Value注解的后处理器
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
// 添加一个协助@Value值获取的后处理器,一般配合AutowiredAnnotationBeanPostProcessor后处理器使用
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// 添加一个解析@Resource,@PostConstruct,@PreDestroy注解的后处理器
context.registerBean(CommonAnnotationBeanPostProcessor.class);
// 添加对@ConfigurationProperties注解解析的后处理器
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
//初始化容器--执行beanFactory后处理器,添加bean后处理器,初始化所有单例
context.refresh();
System.out.println(context.getBean(Bean4.class));
//销毁容器
context.close();
}
}
运行结果如下:
@Autowired 生效:com.cherry.a04.Bean3@77167fb7
@Autowired 生效:com.cherry.a04.Bean2@2f112965
@Value 生效:/opt/development_tools/jdk21/jdk-21.0.3
@PostConstruct 生效
Bean4{home='/usr/lib/jvm/jdk-21-oracle-x64', version='21.0.3'}
@PreDestroy 生效
关于Bean后处理器 AutowiredAnnotationBeanPostProcessor 的运行分析:
编写如下代码:
public class DigInAutowired {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2", Bean2.class);
beanFactory.registerSingleton("bean3", Bean3.class);
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// 1.创建一个后处理器对象
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
processor.postProcessProperties(null,bean1,"bean1"); // 执行依赖注入@Autowired@Value
System.out.println(bean1);
}
}
debug进入到postProcessProperties方法中去:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 首先找到有没有加@Autowired注解的属性,方法,找到后封装到 InjectionMetadata 中
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//通过反射给属性赋值,set方法反射调用等
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var6) {
BeanCreationException ex = var6;
throw ex;
} catch (Throwable var7) {
Throwable ex = var7;
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
}
除此之外我们还可以使用反射的机制手动获取@Autowird和@Value注解上的信息:
public class DigInAutowired {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2", Bean2.class);
beanFactory.registerSingleton("bean3", Bean3.class);
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// 1.创建一个后处理器对象
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
// processor.postProcessProperties(null,bean1,"bean1"); // 执行依赖注入@Autowired@Value
// System.out.println(bean1);
Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Bean1.class);
findAutowiringMetadata.setAccessible(true);
//反射调用该方法:获取bean1上加了@Autowired和@Value注解上的信息,包括成员变量和方法参数
Object injectionMetaData = (InjectionMetadata)findAutowiringMetadata.invoke(processor,"bean1", Bean1.class, null);
System.out.println(injectionMetaData);
}
}
4. 常见工厂后处理器
BeanFactory后处理器的作用:为BeanFactory提供扩展。
例如:
首先编写如下Bean代码:
Config:
@Configuration
@ComponentScan("com.cherry.a05.component")
public class Config {
private Bean1 bean1;
@Bean
public Bean1 bean1(){
return new Bean1();
}
}
Bean1:
@Component
public class Bean1 {}
编写主方法查看此时能否获取Bean对象
public class A05Application {
private static final Logger logger = LoggerFactory.getLogger(A05Application.class);
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
context.refresh(); //初始化容器
for(String name:context.getBeanDefinitionNames()){
System.out.println(name);
}
}
}
config
我们发现只有我们手动加入的bean,而组建扫描并未生效,因此被@Bean注解的方法也未加入到容器中。
因此我们们需要加入一个可以解析@@ComponentScan注解信息的bean工厂后处理器:
public class A05Application {
private static final Logger logger = LoggerFactory.getLogger(A05Application.class);
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(ConfigurationClassPostProcessor.class);
// 扫描mybatias的Mapper接口,并将这些就接口加入到容器中
context.registerBean(MapperScannerConfigurer.class);
context.registerBean("config",Config.class);
context.refresh(); //初始化容器
for(String name:context.getBeanDefinitionNames()){
System.out.println(name);
}
}
}
此时再次运行:
config
bean2
bean3
bean4
bean1
ConfigurationClassPostProcessor处理器支持对@ComponentScan,,@Bean,@Import,@ImportResource 注解的解析
5. 工厂后处理器的模拟实现
5.1 组件扫描
public class A06ApplicationTest {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
//查找类上有没有加@ComponentScan注解
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if(componentScan != null){
//获取注解上的属性(包路径)
for (String p : componentScan.basePackages()) {
// System.out.println(p); // com.cherry.a05.component
// 修改包名转为路径 --> 子包下的所有的类
String packagePath = "classpath*:"+p.replace(".","/")+"/**/*.class";
// System.out.println(packagePath);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
Resource[] resources = context.getResources(packagePath);
for(Resource res:resources){
// System.out.println(res);
MetadataReader reader = factory.getMetadataReader(res);
System.out.println(reader.getClassMetadata().getClassName());
// 判断是否加入了@Component
System.out.println("是否加了@Component: "+reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
System.out.println("是否加了@Component及其派生注解: "+reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
if(reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()) ||
reader.getAnnotationMetadata().hasAnnotation(Component.class.getName())){
// 创建一个BeanDefinition
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(reader.getClassMetadata().getClassName()).getBeanDefinition();
// 为BeanDefinition生成Bean Name
AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
String beanName = beanNameGenerator.generateBeanName(bd, context.getDefaultListableBeanFactory());
// 将BeanDefinition加入到BeanFactory中
context.getDefaultListableBeanFactory().registerBeanDefinition(beanName, bd);
}
}
}
}
context.refresh();
System.out.println("===========");
for(String name:context.getBeanDefinitionNames()){
System.out.println(name);
}
}
}
运行结果如下:
com.cherry.a05.component.Bean2
是否加了@Component: true
是否加了@Component及其派生注解: false
com.cherry.a05.component.Bean3
是否加了@Component: true
是否加了@Component及其派生注解: false
com.cherry.a05.component.Bean4
是否加了@Component: false
是否加了@Component及其派生注解: true
09:19:43.994 [main] INFO com.cherry.a05.component.Bean2 -- 我被spring容器管理了...
09:19:44.011 [main] INFO com.cherry.a05.component.Bean3 -- 我被spring容器管理了...
09:19:44.012 [main] INFO com.cherry.a05.component.Bean4 -- 我被spring容器管理了...
===========
bean2
bean3
bean4
Process finished with exit code 0
把上述的组件扫描抽象出一个BeanFactoryPostProcessor:
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
// postProcessBeanFactory在context.refresh()时调用
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
try {
//查找类上有没有加@ComponentScan注解
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if(componentScan != null){
//获取注解上的属性(包路径)
for (String p : componentScan.basePackages()) {
// System.out.println(p); // com.cherry.a05.component
// 修改包名转为路径 --> 子包下的所有的类
String packagePath = "classpath*:"+p.replace(".","/")+"/**/*.class";
// System.out.println(packagePath);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(packagePath);
for(Resource res:resources){
// System.out.println(res);
MetadataReader reader = factory.getMetadataReader(res);
System.out.println(reader.getClassMetadata().getClassName());
// 判断是否加入了@Component
System.out.println("是否加了@Component: "+reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
System.out.println("是否加了@Component及其派生注解: "+reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
if(reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()) ||
reader.getAnnotationMetadata().hasAnnotation(Component.class.getName())){
// 创建一个BeanDefinition
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(reader.getClassMetadata().getClassName()).getBeanDefinition();
// 为BeanDefinition生成Bean Name
AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
// 判断 configurableListableBeanFactory 是否为 DefaultListableBeanFactory 的实现
if (configurableListableBeanFactory instanceof DefaultListableBeanFactory beanFactory) {
String beanName = beanNameGenerator.generateBeanName(bd, beanFactory);
// 将BeanDefinition加入到BeanFactory中
beanFactory.registerBeanDefinition(beanName, bd);
}
}
}
}
}
} catch (Exception e){
e.printStackTrace();
}
}
}
在主方法直接将bean工厂后处理器注册到bean工厂中即可:
context.registerBean(ComponentScanPostProcessor.class);
5.2 对@Bean注解的解析
将@Bean标注的方法变成BeanDefinition并加入到容器中。
@SpringBootApplication
public class A06ApplicationTest {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// 读取Config类的信息
MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/cherry/a05/Config.class"));
// 拿到所有被@Bean注解标记的方法
Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for(MethodMetadata metadata:methods){
System.out.println(metadata.toString());
// 将方法信息生成对应的BeanDefinition
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.setFactoryMethodOnBean(metadata.getMethodName(), "config");
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
AbstractBeanDefinition bd = builder.getBeanDefinition();
// 加入到BeanFactory中
context.getDefaultListableBeanFactory().registerBeanDefinition(metadata.getMethodName(),bd);
}
context.refresh();
System.out.println("===========");
for(String name:context.getBeanDefinitionNames()){
System.out.println(name);
}
}
}
5.3 对@Mapper注解的解析
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) {
// 扫描Mapper包下的资源
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = resolver.getResources("classpath:com/cherry/a05/mapper/**/*.class");
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
for(Resource res:resources){
MetadataReader reader = metadataReaderFactory.getMetadataReader(res);
ClassMetadata classMetadata = reader.getClassMetadata();
// 判断是否为接口
if (classMetadata.isInterface()) {
// 生成对应的 BeanDefinition
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class).
addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)//设置自动装配
.getBeanDefinition();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
String beanName = generator.generateBeanName(bd, beanFactory);
beanFactory.registerBeanDefinition(beanName, bd);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinitionRegistryPostProcessor.super.postProcessBeanFactory(beanFactory);
}
}
标签:生命周期,System,class,Bean,处理器,context,println,public,out
From: https://www.cnblogs.com/lilyflower/p/18240615