Spring注解源码分析

我们知道如果想使用spring注解你需要在applicationContext.xml配置文件中设置context:component-scan base-package='xxx’这样spring会帮助我们扫描你所设置的目录里面所有的Bean,如果Bean上面有相应的@Service,@Controller注解(当然还有其他的,这里就不一一列出来),那么Spring的IOC容器将会帮我实例对象,设置属性。

分析spring如果实现注解驱动

还是从spring配置文件的命名空间入手,不清楚的可以参考我之前的文章。找到spring-context包进入文件里面找到src/main/resources/META-INF/spring.handlers这样你可以看到一下内容:

http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler

可以看到context命名空间解析的类org.springframework.context.config.ContextNamespaceHandler所以可以直接定位到spring扫描的过程。

spring源码分析-ContextNamespaceHandler

//组件扫描
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());

整个扫描包路径的过程如下:

取出自定义base-package路径

创建ClassPathBeanDefinitionScanner对象并且设置springIOC容器所关心的注解@Component换言之:只要类定义上面有@Component注解那么我们的扫描器就需要处理这个类。

设置BeanName生成工具(这里是生成类名的工具有默认的beanName,也有自定义@Service(“abc”))
开始扫描包,使用ClassReader扫描所有类可以得到类的信息,对比是否有@Component注解,如果有生成BeanDefinition=ScannedGenericBeanDefinition

注册Spring内置的BeanPostProcessor对象。默认有8个org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)主要需要注意的有四个

ConfigurationClassPostProcessor:处理配置类
AutowiredAnnotationBeanPostProcessor:处理@Autowired帮助类注入属性
RequiredAnnotationBeanPostProcessor:处理@required
CommonAnnotationBeanPostProcessor:处理@Resource帮助类注入属性

入口代码:

 if (annotationConfig) {//这里会注册很多内容BeanPostProcessor类Set<BeanDefinitionHolder> processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}

上面只是注册了所有内置Annotation工具类,还没有实例化。接下来我们要进入refresh()方法看看基于注解的类实例化过程

注解类实例过程

在前面基于注解的类已经被扫描成为ScannedGenericBeanDefinition现在就要实例化了。再refresh()方法中首先需要注册前面说的内置处理Annotation类的工具类,没错就是这几个:

2 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
3 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
4 = "org.springframework.context.annotation.internalRequiredAnnotationProcessor"
5 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
6 = "org.springframework.context.event.internalEventListenerProcessor"
7 = "org.springframework.context.event.internalEventListenerFactory"
//最终这些类变为:
0 = {ApplicationContextAwareProcessor@1792} 
1 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@1961} 
2 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@2193} 
3 = {CommonAnnotationBeanPostProcessor@2135} 
4 = {AutowiredAnnotationBeanPostProcessor@1991} 
5 = {RequiredAnnotationBeanPostProcessor@2107} 
6 = {ApplicationListenerDetector@2194} 

入口在:registerBeanPostProcessors(beanFactory);这里会将上面的类注册到IOC容器中,然后根据Bean的生命周期中的第6步设置属性,依据Annotation的方式注入属性:CommonAnnotationBeanPostProcessor来处理属性的注入。我们使用了@Resource来配置属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux查看和修改PATH环境变量的方法

查看PATH&#xff1a;echo $PATH以添加mongodb server为列修改方法一&#xff1a;export PATH/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $PATH查看配置结果。生效方法&#xff1a;立即生效有效期限&#xff1a;临时改变&#xff0c;只能在当前的终端窗口中有效&…

GLog 初始化说明

#include <iostream> #include <glog/logging.h>int main(int argc, char* argv[]) {google::InitGoogleLogging(argv[0]);FLAGS_logtostderr false; // 是否将日志输出到stderr而非文件。FLAGS_alsologtostderr false; //是否将日志输出到文件和stderr&#xff…

Spring ConfigurationClassPostProcessor Bean解析及自注册过程

一bean的自注册过程 二,自注册过程说明 1 configurationclassparser解析流程 1、处理PropertySources注解&#xff0c;配置信息的解析 2、处理ComponentScan注解&#xff1a;使用ComponentScanAnnotationParser扫描basePackage下的需要解析的类(SpringBootApplication注解也包…

新华社:华尔街专家警告2019年美股或面临剧烈调整

新华社&#xff1a;华尔街专家警告2019年美股或面临剧烈调整 2018年08月14日 12:34 新华社新浪财经APP缩小字体放大字体收藏微博微信分享转载于:https://www.cnblogs.com/hjlweilong/p/9664677.html

java定义注解

小伙伴们。今天我们来说说注解、标志 。针对java不同版本来说&#xff0c;注解的出现是在jdk1.5 但是在jdk1.5版本使用注解必须继续类的方法的重写&#xff0c;不能用于实现的接口中的方法实现&#xff0c;在jdk1.6环境下对于继续和实现都是用。 jdk1.5版本内置了三种标准的注…

2018.09.18 while循环

** "loop" 循环 注意要有引号。 **pass 过 #打印 1-100start 1 while start < 101:print("loop",start)start 1 #打印1-49&#xff0c;81-100. 60-80的平方start 1 while start <101 :if start >49 and start < 60:passelif start >5…

2019第二周作业

基础作业 实验代码 #include<stdlib.h> int main(void) {FILE*fp;int num[4],i,b,max;char op;if((fpfopen("c:\\tmj.txt","r"))NULL){ printf("File open error!\n"); exit(0);}for(i0;i<4;i){fscanf(fp,"%d%c",&nu…

实验一(高见老师收)

学 号201521450016 中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告 实验一 网络侦查与网络扫描 学生姓名 陈璪琛 年级 2015 区队 五 指导教师 高见 信息技术与网络安全学院 2018年9月18日 实验任务总纲 2018—2019学年…

GitHub笔记(二)——远程仓库的操作

二 远程仓库 1 创建联系 第1步&#xff1a;创建SSH Key。在用户主目录下&#xff0c;看看有没有.ssh目录&#xff0c;如果有&#xff0c;再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件&#xff0c;如果已经有了&#xff0c;可直接跳到下一步。如果没有&#xff0c;打开S…

QT 子窗体 最大化 界面显示不对

QT 子窗体 最大化 复原 遇到的问题 项目中有个需求&#xff0c;主窗体中嵌套子窗体&#xff0c;需要将子窗体最大化显示和复原。 查了很多资料&#xff0c;基本上都是提到&#xff1a;QT中窗口部件QWidget成员函数showFullScreen();是用于将窗口部件全屏显示&#xff0c;但是他…

Spring 钩子之BeanFactoryPostProcessor和BeanPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor这两个接口都是初始化bean时对外暴露的入口之一&#xff0c;和Aware类似&#xff08;PS:关于spring的hook可以看看Spring钩子方法和钩子接口的使用详解讲的蛮详细&#xff09;本文也主要是学习具体的钩子的细节&#xff0c;以便于实…

什么是HTML DOM对象

HTML DOM 对象 HTML DOM Document 对象 Document 对象 每个载入浏览器的 HTML 文档都会成为 Document 对象。 Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。 提示&#xff1a;Document 对象是 Window 对象的一部分&#xff0c;可通过 window.document 属…

Python3 matplotlib的绘图函数subplot()简介

Python3 matplotlib的绘图函数subplot()简介 一、简介 matplotlib下, 一个 Figure 对象可以包含多个子图(Axes), 可以使用 subplot() 快速绘制, 其调用形式如下 : subplot(numRows, numCols, plotNum) 图表的整个绘图区域被分成 numRows 行和 numCols 列 然后按照从左到右&…

signal(SIGHUP, SIG_IGN);

signal(SIGHUP, SIG_IGN); 的理解转载于:https://www.cnblogs.com/lanjiangzhou/p/10505653.html

spring钩子

Spring钩子方法和钩子接口的使用详解 前言 SpringFramework其实具有很高的扩展性&#xff0c;只是很少人喜欢挖掘那些扩展点&#xff0c;而且官方的Refrence也很少提到那些Hook类或Hook接口&#xff0c;至于是不是Spring官方有意为之就不得而知。本文浅析一下笔者目前看到的S…

【bitset 技巧 分块】bzoj5087: polycomp

神仙zq发现了${n^2\sqrt n}\over 32$做法 Description 你有三个系数为0,1的多项式f(x),g(x),h(x)求f(g(x)) mod h(x)为方便起见&#xff0c;将答案多项式所有系数对2取模输出即可如果f(x)Sigma(Ak * Xk)则f(g(x))Sigma(Ak(g(x))KInput 一共三行&#xff0c;每行一个多项式,分别…

day 012 生成器 与 列表推导式

生成器的本质就是迭代器&#xff0c;写法和迭代器不一样&#xff0c;用法一样。 获取方法&#xff1a; 1、通过生成器函数 2、通过各种推导式来实现生成器 3、通过数据的转换也可以获取生成器 例如&#xff1a; 更改return 为 yield 即成为生成器 该函数就成为了一个生成器函数…

数据库设计注意事项和原则

引言数据库设计是信息系统设计的基础&#xff0c;一个好的数据库设计在满足了软件需求之外&#xff0c;还要易维护、易扩充等等要求。当然&#xff0c;对专家们反复强调的数据的一致性、冗余性、访问效率等问题的解决&#xff0c;很大程度上取决于数据库设计者的经验和专业水平…

【AtCoder】ARC078

C - Splitting Pile 枚举从哪里开始分的即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar(\n) #define MAXN 200005 #defi…

20172325 2018-2019-1 《Java程序设计》第二周学习总结

20172325 2018-2019-1 《Java程序设计》第二周学习总结 教材学习内容总结 3.1集合 集合是一种聚集、组织了其他对象的对象。集合可以分为两大类&#xff1a;线性集合和非线性集合。线性集合&#xff1a;一种其元素按照直线方式组织的集合。非线性集合&#xff1a;一种其元素按某…