spring mvc 入口 DispatcherServlet,类关系图如下所示

DispatcherServlet 就是一个 Servlet,那Servlet 的初始化方法 init()在哪里,通过类图可知,可以查看 HttpServletBean 中的 init() 方法,进行 Servlet初始化.

xml解析和注解 解析入口

经过一些xml和spring 初始化配置加载后,进入AbstractApplicationContext#refresh()方法

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

进入 AbstractRefreshableApplicationContext#refreshBeanFactory()方法,通过 loadBeanDefinitions(beanFactory) 方法解析 xml 和注解

  • xml的解析类

    AbstractXmlApplicationContext
  • 注解的解析类

    AnnotationConfigWebApplicationContext

xml 解析过程 类的流转

  • 将xml 或 properties 通过 ResourceLoader 加载为 Resource 对象,得到 Resource 对象就得到了文件所对应的 文件流,这个文件流在解析 xml 时会用到。
  • 每个 Resource 对象 都有对应的 Reader对象,Reader对象将配置封装成 BeanDefinition
  • BeanDefinition 在放入 map或容器中 

  1. ClassPathXmlApplicationContext#getConfigResources() 方法中,通过 getConfigResources() 这个方法将 所有 xml 文件封装成 Resource对象
  2. 循环 resource 对象,解析每个xml文件
    1. 进入 XmlBeanDefinitionReader 类中的 loadBeanDefinitions 方法进行xml 解析

      spring 使用 dom4j 解析xml
    2. 在 DefaultBeanDefinitionDocumentReader#parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) 方法中,通过 xml 的root根节点判断是默认的标签还是自定义的标签,分别进行解析。
    3. 通过xml根节点获取所有子节点,循环每个子节点,并判断子节点是默认标签还是自定义标分别进行解析。
    4. 将每个标签的元素解析后封装为 BeanDefinition 对象。 BeanDefinition 对象再封装为 BeanDefinitionHolder 对象,BeanDefinitionHolder包含 bean的名字、别名和 bean的BeanDefinition对象.

默认标签:import标签、alias 标签、bean 标签 、beans 标签

自定义标签:spring mvc 自定义的标签和自己扩展的标签等

BeanDefinition 说明

  • 我们会把xml里面的标签元素比如:bean、componentScan、annotation-config 等标签封装成 beanDefinition 对象
  • 我们会把 annotation比如:@Service、@Controller、@Component、@Resource 等注解封装成 BeanDefinition

自定义标签解析

  1. 命名空间 namespaceUri, 也就是 beans 标签的 xmlns 、 xmlns:context、xmlns:aop、xmlns:tx 后面uri
  2. 当解析某个标签时会 根据某个标签获取对应的命名空间uri,具体查看 BeanDefinitionParserDelegate#parseCustomElement(Element ele)方法
  3. 通过解析命名空间 uri,并实例化所对应的 命名空间处理类对象,这个解析过程会调用 命名空间处理类中的 init()方法,注册所有关于这个命名空间 有关元素的所有解析器。具体查看 DefaultNamespaceHandlerResolver#resolve(String namespaceUri)方法
  4. 调用某个命名空间的处理器的 parse方法,例如:ContextNamespaceHandler 类是 xmlns:context 的命名空间处理类

查看 xmlns:context 的命名空间

  1. 进入 spring-context 模块
  2. 进入 resources/META-INF/ 文件夹下面
  3. 查看 spring.handlers 配置文件 可以看到每个命名空间的 uri 对应一个类。

    例如 xmlns:context 对应的 uri http://www.springframework.org/schema/context 对应 ContextNamespaceHandler 类 每一个命名空间都有对应的解析类 NamespaceHandler ,每一个 命名空间解析类中都有所对应的 命名空间的元素解析器.
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler

context 命名空间 说明

例如:<context:annotation-config />

context找uri,beans标签中有content对应的uri。

spring.handlers里面就有uri对应的处理类,实现NamespaceHandler接口,就会把这个命名空间对应的标签对应的处理注册进来。

如果解析标签 component-scan 时,那么解析类就是 ComponentScanBeanDefinitionParser 类,并调用 component-scan 标签对应解析类的 parse 方法进行解析

在ComponentScanBeanDefinitionParser解析类里面完成了

  1. 基本包的扫描
  2. 类型过滤器的配置
  3. annotation-config配置的兼容
  4. 注解处理器BeanPostProcessor的注册

分析 AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);

  1. AutowiredAnnotationBeanPostProcessor 类 就是 @Autowire 注解的支持
  2. RequiredAnnotationBeanPostProcessor 类 就是 @Required 注解的支持
  3. CommonAnnotationBeanPostProcessor 类就是对 jsr250的支持,也就是 @Resources

所有生成的beanDifinition对象都会注册缓存到beanDefinitionMap中key就是beanName,value 就是beanDefinition , 然后会把beanName放到List里面去,beanDifinitionNames 就是这个list

1-spring xml 和 注解 解析过程的更多相关文章

  1. Spring 缓存注解解析过程

    Spring 缓存注解解析过程 通过 SpringCacheAnnotationParser 的 parseCacheAnnotations 方法解析指定方法或类上的缓存注解, @Cacheable ...

  2. spring ioc 源码分析之-- beanDefinition的加载过程以及ComponentScan,@componet,@import @Bean等注解解析过程

    背景:我们启动主启动类后,相应的bean就被扫描进来了,原理是啥? 实现该功能的主要核心类就是:ConfigurationClassPostProcessor,我们看看他的继承体系: 它实现了Bean ...

  3. spring.xml及注解

    spring.xml配置文件中配置注解: 开启注解(及自动扫描包中bean): 1:<context:component-scan base-package="com.bzu" ...

  4. spring cron表达式及解析过程

    1.cron表达式 cron表达式是用来配置spring定时任务执行时间的字符串,由5个空格分隔成的6个域构成,格式如下: {秒}  {分}  {时}  {日}  {月}  {周} 每一个域的含义解释 ...

  5. 2015年12月10日 spring初级知识讲解(二)最小化Spring XML配置 注解

    序,随着Spring容器管理Bean数量增加,XML文件会越来越大,而且纯手工配置XML很繁琐,Spring和JAVA都提供了一些注解方式用以简化XML配置. 目录 一.自动装配(autowiring ...

  6. [转] Spring4.3.x 浅析xml配置的解析过程(6)——解析context命名空间之property-placeholder和property-override标签

    在上一篇解析自定义命名空间的标签中,我们已经知道解析自定义命名空间的标签需要用到NamespaceHandler接口的实现类,并且知道spring是如何获取命名空间对应的命名空间处理器对象的.因此我们 ...

  7. Java#Spring框架下注解解析

    @Bean 定义Bean @Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里.添加的bean的id为方法名 @Configura ...

  8. 这一次搞懂Spring自定义标签以及注解解析原理

    前言 在上一篇文章中分析了Spring是如何解析默认标签的,并封装为BeanDefinition注册到缓存中,这一篇就来看看对于像context这种自定义标签是如何解析的.同时我们常用的注解如:@Se ...

  9. iOS开发笔记3:XML/JSON数据解析

    这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...

随机推荐

  1. 使用ResourceBundle 类读取 src 下的 xxx.properties 文件

    之前要读取 src 下的 .properties 文件都是使用的类加载器,加载类路径下的资源文件当做一个流来处理,load 到一个 Properties 对象上. jdbc.properties 代码 ...

  2. inline函数的总结

    在函数返回类型前加上关键字inline就可以将函数指定为内联函数: inline const string& shortString(const string &s1, const s ...

  3. app耗电量测试工具--PowerTutor

    PowerTutor是一款用来测试手机功耗的小工具,它可以只管地展示手机系统主要的组件和各种用户app产生的功耗数据.它可以统计app的屏幕功耗(LCD).CPU功耗以及WiFi和3G网络功耗,我们可 ...

  4. 【Python】Python对象类型及其运算

    Python对象类型及其运算 基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = ...

  5. ZOJ3084_S-Nim

    题目的意思是这样的,给定你若干堆石子,每次你可以从任一堆取出某些固定数量的石子,每次取完后必须保证没堆石子的数量不为0,谁无法操作了就算fail. 刚刚开始看题目的时候有点也没有思路,甚至连Sg函数也 ...

  6. MethodHandle

    JDK7为间接调用方法引入新的API,在java.lang.invoke包下,可以看作为反射的升级版,但它不像反射API那样显得冗长.繁重 主要的类 MethodHandle 方法句柄.对可直接执行的 ...

  7. C++解析-外传篇(1):异常处理深度解析

    0.目录 1.异常的最终处理 2.结束函数terminate() 3.小结 1.异常的最终处理 问题: 如果在main函数中抛出异常会发生什么? 如果异常不处理,最后会传到哪里? 下面的代码的输出什么 ...

  8. QString::QString 中文乱码

    QString::QString 中文乱码 处理方法: 1. QString str = QString::fromLocal8Bit("中文"); // vs2008 vs200 ...

  9. 【刷题】BZOJ 1951 [Sdoi2010]古代猪文

    Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久 ...

  10. 【单调队列】【P3957】 跳房子

    传送门 Description 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 $n$ 个格子,这些格子都 ...