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);复制代码
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- FlinkSQL 动态加载 UDF 实现思路
- 基于Spring+Angular9+MySQL开发平台
- 网络比15年前更慢错误更多?开发者加载了100万个网站实测
- 别不拿GateWay当回事,SpringCloud告诉你错了
- web 安全之 Spring Security 入门教程
- Spring Application实例化流程和构造方法参数
- SpringBoot常用注解
- 阿里爆款SpringBoot项目实战PDF+源码+视频分享
- Firefox 83将默认启用Warp更新:大幅提升响应时间和加载速度
- SpringCloud下skywalking的快速入门