数码资讯
1-spring xml 和 注解 解析过程
spring mvc 入口 DispatcherServlet,类关系图如下所示 DispatcherServlet 就是一个 Servlet,那Servlet 的初始化方法 init()在哪里,通过类图可知,可以查看 HttpServletBean 中的 init() 方法,进行 Servlet初
选购提示
关注价格、性能、续航、售后和真实使用场景,理性比较后再下单。
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或容器中
- ClassPathXmlApplicationContext#getConfigResources() 方法中,通过 getConfigResources() 这个方法将 所有 xml 文件封装成 Resource对象
- 循环 resource 对象,解析每个xml文件
- 进入 XmlBeanDefinitionReader 类中的 loadBeanDefinitions 方法进行xml 解析 spring 使用 dom4j 解析xml
- 在 DefaultBeanDefinitionDocumentReader#parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) 方法中,通过 xml 的root根节点判断是默认的标签还是自定义的标签,分别进行解析。
- 通过xml根节点获取所有子节点,循环每个子节点,并判断子节点是默认标签还是自定义标分别进行解析。
- 将每个标签的元素解析后封装为 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
自定义标签解析
- 命名空间 namespaceUri, 也就是 beans 标签的 xmlns 、 xmlns:context、xmlns:aop、xmlns:tx 后面uri
- 当解析某个标签时会 根据某个标签获取对应的命名空间uri,具体查看 BeanDefinitionParserDelegate#parseCustomElement(Element ele)方法
- 通过解析命名空间 uri,并实例化所对应的 命名空间处理类对象,这个解析过程会调用 命名空间处理类中的 init()方法,注册所有关于这个命名空间 有关元素的所有解析器。具体查看 DefaultNamespaceHandlerResolver#resolve(String namespaceUri)方法
- 调用某个命名空间的处理器的 parse方法,例如:ContextNamespaceHandler 类是 xmlns:context 的命名空间处理类
查看 xmlns:context 的命名空间
- 进入 spring-context 模块
- 进入 resources/META-INF/ 文件夹下面
- 查看 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解析类里面完成了
- 基本包的扫描
- 类型过滤器的配置
- annotation-config配置的兼容
- 注解处理器BeanPostProcessor的注册
分析 AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
- AutowiredAnnotationBeanPostProcessor 类 就是 @Autowire 注解的支持
- RequiredAnnotationBeanPostProcessor 类 就是 @Required 注解的支持
- CommonAnnotationBeanPostProcessor 类就是对 jsr250的支持,也就是 @Resources
所有生成的beanDifinition对象都会注册缓存到beanDefinitionMap中key就是beanName,value 就是beanDefinition , 然后会把beanName放到List里面去,beanDifinitionNames 就是这个list
声明:本文内容用于数码产品信息整理与选购参考,具体价格、库存、售后政策以官方渠道和电商页面实时信息为准。