Spring Bean加载流程分析(通过 XML 方式加载)( 二 )
通过该构造方法 , 我们可以知道该构造方法初始了一个类加载器 。 如果类加载器不为空 , 则复制成默认的类加载器 。 如果类加载器为空 , 则通过 ClassUtils.getDefaultClassLoader() 方法获取一个默认的类加载器 。 而我们传入的类加载器显然为 null , 则 Spring 会去自动获取默认的类加载器 。
public static ClassLoader getDefaultClassLoader() {ClassLoader cl = null;try {//1.获取当前线程的类加载器cl = Thread.currentThread().getContextClassLoader();}catch (Throwable ex) {// Cannot access thread context ClassLoader - falling back...}if (cl == null) {// No thread context class loader -> use class loader of this class.// 2. 获取当前类的类加载器cl = ClassUtils.class.getClassLoader();if (cl == null) {// getClassLoader() returning null indicates the bootstrap ClassLoadertry {//获取系统级的类加载器/应用类加载器 AppClassLoadercl = ClassLoader.getSystemClassLoader();}catch (Throwable ex) {// Cannot access system ClassLoader - oh well, maybe the caller can live with null...}}}return cl;}复制代码
通过 getDefaultClassLoader 方法我们可以知道 , Spring 在获取类加载器做了如下三件事:
- 获取当前线程的类加载器 , 如果存在 , 则返回 。 不存在则往下执行
- 获取加载当前类的类加载器 , 如果存在 , 则返回 。 不存在则往下执行
- 如果以上两步均没有获取到类加载器 , 则获取系统级类加载器/应用类加载器 。
2. 初始化 BeanFactory接下来我们看示例代码中的第二行代码的实现
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();复制代码
看看 new DefaultListableBeanFactory() 方法做了什么?/** * 创建一个默认的 BeanFactory * Create a new DefaultListableBeanFactory. */public DefaultListableBeanFactory() {super();}复制代码
一个空的实现 , 但是调用了父类的构造方法 , 跟进一步 , 看看父类的构造方法做了什么事情 。public AbstractAutowireCapableBeanFactory() {super();ignoreDependencyInterface(BeanNameAware.class);ignoreDependencyInterface(BeanFactoryAware.class);ignoreDependencyInterface(BeanClassLoaderAware.class);}复制代码
同样 , 该构造方法也调用了父类的构造方法 , 跟进父类的构造方法一探究竟 。public AbstractBeanFactory() {}复制代码
空实现 , 没啥好看的 。 看看 AbstractAutowireCapableBeanFactory 里面的另外三个方法 。 通过方法的名称我们可以大致猜出 , 这是为了忽略某些特定的依赖接口 。private final Set> ignoredDependencyInterfaces = new HashSet<>();public void ignoreDependencyInterface(Class> ifc) {this.ignoredDependencyInterfaces.add(ifc);}复制代码
没有太多的复杂逻辑 , 只是将某些特定的 class 对象放进了一个 set 集合中 , 标记这些接口应该被忽略 , 或许这个 set 集合会在后面的某一处使用到 。 但是注意 , 只有 BeanFactory 的接口应该被忽略 。3. 定义 BeanDefinitionReader 对象接下来我们看第三行代码的实现
BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);复制代码
- 文件系统(02):基于SpringBoot管理Xml和CSV
- SpringBoot2.x入门到项目实战课程系列(第二章)
- SpringBoot集成Mybatis
- 大牛深入解析SpringBoot核心运行原理和运作原理源码
- SpringBoot写后端接口,看这一篇就够了
- 9款游戏13块SSD:测试固态硬盘对游戏加载速度影响有多大?
- Spring Boot 中 @EnableX 注解的驱动逻辑
- SpringBoot2.x入门到项目实战课程系列(第五章)
- SpringBoot整合JWT+Shiro
- 14 个 SpringMVC顶级技巧,随时用随时爽