当前位置: 首页 > news >正文

Spring之【AnnotatedBeanDefinitionReader】

目录

上一章回顾

前置知识

DefaultListableBeanFactory

beanDefinitionMap属性

beanDefinitionNames属性

registerBeanDefinition(String name, BeanDefinition beanDefinition)方法

AnnotationConfigUtils

部分常量

registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source)方法

BeanDefinitionReaderUtils

registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)方法

这里先简单说下部分内部组件Bean的作用

ConfigurationClassPostProcessor

AutowiredAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor

AnnotatedBeanDefinitionReader

构造器

register(Class... componentClasses)方法

使用AnnotationConfigApplicationContext容器进行测试看下效果

自定义一个组件类

自定义一个实现了BeanDefinitionRegistryPostProcessor的组件类

编写测试类

运行结果

调试程序,看容器中的beanDefinitionMap集合 


上一章回顾

        主要讲述的是BeanDefinition,意为Bean的定义信息,记录了Bean是否为单例、是否懒加载等信息,Spring先将需要管理的Bean所对应的BeanDefinition信息存储起来,然后再进行后续操作,如:BeanFactoryPostProcessor的实例化和回调、Bean的实例化、BeanPostProcessor的before方法回调、Bean的初始化、BeanPostProcessor的after方法回调等。

前置知识

DefaultListableBeanFactory

beanDefinitionMap属性

// 用于存放容器中的Bean定义信息
// key:beanName
// value:BeanDefinition对象
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

beanDefinitionNames属性

// bean名字的集合
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

registerBeanDefinition(String name, BeanDefinition beanDefinition)方法

/*** 对BeanDefinitionRegistry接口中的registerBeanDefinition方法的实现*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {// ...// 往容器中添加BeanDefinition信息this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);// ...
}

AnnotationConfigUtils

部分常量

// 容器内部组件Bean:ConfigurationClassPostProcessor的beanName
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalConfigurationAnnotationProcessor";// 容器内部组件Bean:AutowiredAnnotationBeanPostProcessor的beanName
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";// 容器内部组件Bean:CommonAnnotationBeanPostProcessor的beanName
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalCommonAnnotationProcessor";// 容器内部组件Bean:EventListenerMethodProcessor的beanName
public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME ="org.springframework.context.event.internalEventListenerProcessor";// 容器内部组件Bean:DefaultEventListenerFactory的beanName
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME ="org.springframework.context.event.internalEventListenerFactory";

registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source)方法

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {// 获取DefaultListableBeanFactory对象DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 添加ConfigurationClassPostProcessor组件Bean的RootBeanDefinition到容器中if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 添加AutowiredAnnotationBeanPostProcessor组件Bean的RootBeanDefinition到容器中if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// 添加CommonAnnotationBeanPostProcessor组件Bean的RootBeanDefinition到容器中if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// 添加EventListenerMethodProcessor组件Bean的RootBeanDefinition到容器中if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}// 添加DefaultEventListenerFactory组件Bean的RootBeanDefinition到容器中if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;
}// 这里的registry是DefaultListableBeanFactory
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {// ...// 将BeanDefinition添加到容器中,也就是DefaultListableBeanFactory的beanDefinitionMap集合中registry.registerBeanDefinition(beanName, definition);// ...
}

BeanDefinitionReaderUtils

registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)方法

public abstract class BeanDefinitionReaderUtils {// ...public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// 获取beanNameString beanName = definitionHolder.getBeanName();// 将BeanDefinition添加到Spring容器中registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// 处理bean的别名String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}// ...
}

这里先简单说下部分内部组件Bean的作用

ConfigurationClassPostProcessor

  • 识别@ComponentScan注解
  • 识别@Component注解
  • 识别@Configuration注解
  • 识别@Bean注解
  • 识别@Import注解
  • ......

AutowiredAnnotationBeanPostProcessor

  • 识别@Autowired注解
  • 识别@Value注解
  • ......

CommonAnnotationBeanPostProcessor

  • 识别@Resource注解
  • 识别@PostConstruct注解
  • 识别@PreDestroy注解
  • ......

AnnotatedBeanDefinitionReader

构造器

public class AnnotatedBeanDefinitionReader {// ...// 参数可以理解为Spring容器public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {// 调用两个参数的构造器this(registry, getOrCreateEnvironment(registry));}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {// ...// 前置知识中提到的工具类AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}// ...
}public abstract class AnnotationConfigUtils {// ...public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {// 这里调用的是前置知识中提到的AnnotationConfigUtils类的方法// 将Spring内部需要的组件Bean的BeanDefinition信息存放到BeanDefinitionMap集合中registerAnnotationConfigProcessors(registry, null);}// ...
}

register(Class<?>... componentClasses)方法

public class AnnotatedBeanDefinitionReader {// ...// 可以传入多个用户定义的组件类public void register(Class<?>... componentClasses) {// 遍历传入的组件类for (Class<?> componentClass : componentClasses) {registerBean(componentClass);}}public void registerBean(Class<?> beanClass) {doRegisterBean(beanClass, null, null, null, null);}private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {// 用户自定义的组件类对应创建AnnotatedGenericBeanDefinition对象AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);// ...BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 使用前置知识中介绍的工具类添加BeanDefinition到Spring容器中BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}// ...
}

使用AnnotationConfigApplicationContext容器进行测试看下效果

自定义一个组件类

package bean.definition.test;import org.springframework.context.annotation.ComponentScan;/*** 自定义的组件类,添加了@ComponentScan注解*/
@ComponentScan("bean.definition.test")
public class CustomComponent {
}

自定义一个实现了BeanDefinitionRegistryPostProcessor的组件类

package bean.definition.test;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;@Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// 从容器中获取所有的BeanDefinition的beanNameString[] beanDefinitionNames = registry.getBeanDefinitionNames();// 遍历查看for (String beanDefinitionName : beanDefinitionNames) {System.out.println(beanDefinitionName);}}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}

编写测试类

package bean.definition.test;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringBeanDefinitionTest {public static void main(String[] args) {// 1、执行AnnotatedBeanDefinitionReader实例化// 2、执行ClassPathBeanDefinitionScanner实例化// 3、调用AnnotatedBeanDefinitionReader的register方法将传入的组件类的Bean定义对象添加到容器中// 4、执行AbstractApplicationContext的refresh方法new AnnotationConfigApplicationContext(CustomComponent.class);}
}

运行结果

// 5个Spring内部组件beanName(internal)
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory// 2个用户自定义组件beanName
customComponent
customBeanDefinitionRegistryPostProcessor

调试程序,看容器中的beanDefinitionMap集合 

http://www.lryc.cn/news/593345.html

相关文章:

  • 前端面试专栏-工程化:28.团队协作与版本控制(Git)
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现动物分类(C#源码,UI界面版)
  • Selenium 中 findElement 方法全解析:定位网页元素的 7 种方式
  • RPC(Remote Procedure Call,远程过程调用)介绍
  • 探秘边缘安全架构设计要点解析
  • 深入了解 find_element 方法:Web 自动化定位元素的核心​
  • Node.js特训专栏-实战进阶:17.会话管理与安全存储
  • 开发框架安全ThinkPHPLaravelSpringBootStruts2SpringCloud复现
  • SLAM中的非线性优化-2D图优化之激光SLAM基于优化的前端匹配(十八)
  • KVM中使用桥接模式.运维就业技术教程
  • 零基础学习性能测试-linux服务器监控:CPU监控
  • 【RK3576】【Android14】USB开发调试
  • 《Spring Boot 插件化架构实战:从 SPI 到热插拔的三级跳》
  • Android14 SystemUI 启动流程(2)
  • Verilog *2* SPI-立创逻辑派G1测试-1
  • 软件警告弹窗与兼容性问题
  • 当OT遇见IT:Apache IoTDB如何用“时序空间一体化“破解工业物联网数据孤岛困局
  • FMEA-CP-PFD三位一体数字化闭环:汽车部件质量管控的速效引擎
  • XSS漏洞----基于Dom的xss
  • 动态规划算法的欢乐密码(三):简单多状态DP问题(上)
  • GA-BP遗传算法优化BP神经网络数据生成,采用SVM分类模型评估
  • RabbitMQ面试精讲 Day 3:Exchange类型与路由策略详解
  • PostgreSQL常用命令与工具指南
  • 发明专利怎么写,与学术文章异同点与注意事项
  • 从0开始学习R语言--Day51--PH检验
  • HAMR硬盘高温写入的可靠性问题
  • 数字图像处理(三:图像如果当作矩阵,那加减乘除处理了矩阵,那图像咋变):从LED冬奥会、奥运会及春晚等等大屏,到手机小屏,快来挖一挖里面都有什么
  • 我用Cursor,1周上线了一个虚拟资料流量主小程序技术选型
  • 图解系统-小林coding笔记
  • view和pure的区别