网站首页 > 技术教程 正文
Annotation的解析机制
我们在使用spring中,经常会在xml中加上<context:component-scan/>标签,然后在需要配置在spring中的类上加上@Component/@Service/@Repository等注解,我们先简单的看看@Service或者@Repository注解,会发现这两个注解都被@Component注解所标识:
想要了解这些注解是如何工作的,就需要先知道component-scan标签做了什么。前文中描述了spring的xml解析机制以及其扩展方式,既然component-scan标签声明在context这个命名空间中,我们可以从ContextNamespaceHandler类入手,此类中有如下代码:
可以看到,component-scan标签使用了ComponentScanBeanDefinitionParser类做bean的解析,此类中的核心代码比较容易理解,先扫描类路径,识别出@Component注解标识的类或以@Component作为元注解的注解标识的类,将扫描到的bean注册到BeanDefinitionRegistry中:
从ClassPathBeanDefinitionScanner的doScan方法中进入,很容易发现component-scan的类路径扫描策略,它并没有逐个加载class,而是通过读取class文件得到类的元数据的方式做的类识别,关键代码段如下:
registerComponents方法的逻辑前半部分是在处理scanner扫描出来的bean,而后半部分则略有不同,后半部分向spring中注册注解配置处理相关的PostProcessor,主要逻辑是用于处理@Configuration/@ComponentScan注解标识的类以及@Autowired等注解的注入:
进入到AnnotationConfigUtils.registerAnnotationConfigProcessors方法的调用中,可以看到spring注册了多个与注解处理相关的类,其中包括用于处理@Configuration或@ComponentScan注解配置的类ConfigurationClassPostProcessor,注解注入处理类AutowiredAnnotationBeanPostProcessor等,详情可见具体代码:
注册的这些为都是前文描述过的PostProcessor的实现,其中注解注入相关的类是AutowiredAnnotationBeanPostProcessor,前文已经提到过,这里再重点描述一下ConfigurationClassPostProcessor类,此类的定义如下:
ConfigurationClassPostProcessor类是BeanFactoryPostProcessor的实现类(BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口),从ConfigurationClassPostProcessor的postProcessorBeanFactory方法或者postProcessorBeanDefinitionRegistry方法中可以看到注解配置处理的逻辑:
从代码片断中可以看到processConfigBeanDefinitions方法是处理注解的核心方法,进入到此方法中会发现使用了ConfigurationClassParser类做注解解析。 ConfigurationClassParser类的parse方法调用了processConfigurationClass方法,此方法用于处理标识了@Configuration或@ComponentScan的bean,方法中有一段判断是否需要跳过某个class的逻辑:
这里涉及到另一个注解@Conditional,被此注解标识的配置类,在不满足此注解指定的条件时在处理注解配置时会被跳过。
@Import
在使用springboot时,经常会用到@EnableXxx这样的注解,比如开户aop可以使用@EnableAspectJAutoProxy,这里也是使用到了spring为注解配置留的扩展,打开此类可以看到@Import注解的使用:
回到ConfigurationClassParser类中,可以找到处理@Import注解的代码:
首先是collectImports方法,它里面有一个递归调用,用于处理@Import作为元注解的情况,由于有这段逻辑的处理,@EnableAspectJAutoProxy上的元注解@Import才会被识别; 通过processImports方法可以看到@Import的具体处理逻辑,它通过@Import注解中的value属性指定的class获取BeanDefinition对象,逻辑相对较容易理解,这里不做过多解释:
Spring注解的扩展
这里给一个Spring注解扩展的简单示例,在初始化前通过日志打印出spring中配置了哪些bean,通过@Import实现:
在使用时可将@LogBean标识在配置类或者springboot的启动类上:
猜你喜欢
- 2024-10-19 Java 项目编译提示 javax.xml.bind.annotation does not exist 错误
- 2024-10-19 Android annotation包下常用的注解
- 2024-10-19 SpringMVC疑难一:mvc:annotation-dr
- 2024-10-19 Spring 中 AnnotationConfigUtils
- 2024-10-19 spring mvc 配置失效了?(springmvc的配置)
- 2024-10-19 为什么都爱着江南?黛瓦白墙,烟雨朦胧,是文人魂牵梦绕的故乡
- 2024-10-19 Spring框架系列之构造方法底层剖析01
- 2024-10-19 基于.NET6包含DDD,ES,CQRS等概念的开源
- 2024-10-19 spring 中 AnnotationUtils 的常用方法
- 2024-10-19 SpringBoot实战4-Spring基础-IoC容器
你 发表评论:
欢迎- 最近发表
-
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- linux移植(Linux移植freemodbus)
- 独家解读:Win10预览版9879为何无法识别硬盘
- 基于Linux系统的本地Yum源搭建与配置(ISO方式、RPM方式)
- Docker镜像瘦身(docker 减小镜像大小)
- 在linux上安装ollama(linux安装locale)
- 渗透测试系统Kali推出Docker镜像(kali linux渗透测试技术详解pdf)
- Linux环境中部署Harbor私有镜像仓库
- linux之间传文件命令之Rsync傻瓜式教程
- 解决ollama在linux中安装或升级时,通过国内镜像缩短安装时长
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)