Spring 程序入口和xml解析

文章目录


一、Spring 源码下载

1、git clone --branch v5.2.8.RELEASE https://gitee.com/Z201/spring-framework.git

2、gradle 下载,gradle 要 JDK8 的版本。

3、到下载的 spring 源码路径执行 gradle 命令。

gradlew :spring-oxm:compileTestJava

4、用 idea 打开 spring 源码工程,在 idea 中安装插件 kotlin,重启 idea

5、把编译好的源码导入到工程中。

二、新创建maven项目。导入spring的jar

1、Spring 中最核心的 4 个 jar

  • Spring-beans
  • Spring-core
  • Spring-context
  • Spring-expression

2、简单点的spring项目,就需要一个jar包

Spring 程序入口和xml解析

3、可加些点打印日志,lombok等依赖,自定义

Spring 程序入口和xml解析

三、把源码导入到工程

1、找到对接的包,右键点击Open Library Settings

Spring 程序入口和xml解析

2、点击Classes,再点击+号, 添加导入的spring源码spring-context下libs中的jar。

      点击Sources,再点击+号,添加导入的spring源码spring-context下所有文件

Spring 程序入口和xml解析

四、Spring 容器加载方式 (常用两种)

1、类路径获取配置文件

ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");

2、无 配 置 文 件 加 载 容 器 (注解)

ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.own.app");

五、Spring 容器加载核心方法

AbstractApplicationContext.refresh() 方法 refresh()方法是 spring 容器启动过程中的核心方法,spring 容器要加载必须执行该方法。

六、Xml 流程分析

Spring 程序入口和xml解析

七、默认标签解析

默认标签有四个(import、alias、bean、beans)

下面只使用常用的bean标签举例:

1、解析document,将其中bean标签的属性BeanDefinition

// 解析document   封装成BeanDefinition
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

2、注册BeanDefinition,把注册BeanDefinition放到BeanFactory的beanDefinitionMap属性中

// 注册BeanDefinition  , 就是把注册BeanDefinition放到BeanFactory的beanDefinitionMap属性中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

八、自定义标签解析

1、获取自定义标签的 namespace 命令空间:(spring.xml中beans标签xsi:schemaLocation属性值)

// 根据自定义标签的前缀(例如:context:component-scan)  获取beans标签xsi:schemaLocation属性值中对应的uri (http://www.springframework.org/schema/context)
String namespaceUri = getNamespaceURI(ele);

2、根据命令空间获取 NamespaceHandler 对象。

NamespaceUri 和NamespaceHandler 之间会建立一个映射,spring 会从所有的spring jar 包中扫描 spring.handlers 文件,建立映射关系。

// 获取自定义标签的处理器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve( namespaceUri);

上述resolve方法。

// key spring.xml的nameSpaceUri 
// value 是META_INF/spring.handlers文件中映射的类
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);

3、通过反射获取spring.handlerswen文件中类实现了NamespaceHandler接口的类

// 通过反射获取spring.handlerswen文件中类实现了NamespaceHandler接口的类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);

4、初始化 注册解析器存到 NamespaceHandlerSupport的parsers

// 初始化  注册 解析器存到 NamespaceHandlerSupport的parsers
namespaceHandler.init();

5、获取对应的解析类,执行对应的解析方法

// 根据自定义标签的前缀   获取对应的解析类。
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 执行对应的解析方法
return (parser != null ? parser.parse(element, parserContext) : null);

八、BeanDefinition的属性

Spring 程序入口和xml解析
上一篇:简易版的 Spring 之如何实现 Setter 注入


下一篇:Spring 3