文章目录
- 一、Spring 源码下载
- 二、新创建maven项目。导入spring的jar
- 三、把源码导入到工程
- 四、Spring 容器加载方式 (常用两种)
- 五、Spring 容器加载核心方法
- 六、Xml 流程分析
- 七、默认标签解析
- 八、自定义标签解析
- 八、BeanDefinition的属性
一、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
2、简单点的spring项目,就需要一个jar包
3、可加些点打印日志,lombok等依赖,自定义
三、把源码导入到工程
1、找到对接的包,右键点击Open Library Settings
2、点击Classes,再点击+号, 添加导入的spring源码spring-context下libs中的jar。
点击Sources,再点击+号,添加导入的spring源码spring-context下所有文件
四、Spring 容器加载方式 (常用两种)
1、类路径获取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
2、无 配 置 文 件 加 载 容 器 (注解)
ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.own.app");
五、Spring 容器加载核心方法
AbstractApplicationContext.refresh() 方法 refresh()方法是 spring 容器启动过程中的核心方法,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);