点击上方“业余草”,选择“置顶公众号”

第一时间获取技术干货和业界资讯!


Spring IOC 容器为什么不使用 Class.forName 加载类

☞ 免费CSDN资料帮下服务 | 免费加群 ☜

很多人看过 Spring 的源码,但是他们都是为了看源码而看!并没有读懂 Spring 的设计思想,也没有思考过为什么要这样设计!

我在这篇文章《程序员如何阅读源码?大牛是如果形成的?》中,已经写到了如何阅读源码。而我的同事按照上面的步骤并结合自身的情况,再过去的几个月看了不少的源码。最终今年破格加薪 2K !

那么接下来我呀说的是,有哪些是你在看源码的过程中并没有注意的细节和内容。比如,今天我们要学习的Spring IOC 容器为什么不使用 Class.forName 加载类,而是使用 ClassLoader!

Spring IOC 容器为什么不使用 Class.forName 加载类

虽然 Class.forName() 和 ClassLoader 都可用来对类进行加载,但是它们还是有些区别的。为了说明它们,我们来看看 JVM 加载类的步骤是什么!

Spring IOC 容器为什么不使用 Class.forName 加载类

Spring IOC 容器为什么不使用 Class.forName 加载类

清楚上面这个之后,再要想搞明白 Spring Ioc中为什么使用 Classloader,而不是 Class.forName,还得从它们的区别说起。我们先来看看如果使用 Class.forName 会发生什么!

先创建一个测试类。

Spring IOC 容器为什么不使用 Class.forName 加载类

上面的代码中, Class.forName("com.xttblog.Xttblog") 的调用会触发 Xttblog 的静态代码块的执行, 而 ClassLoader.getSystemClassLoader().loadClass("com.xttblog.Xttblog") 并不会。

调用 Class.forName 其实相当于调用了 Class.forName(className, true, currentLoader), 这个方法的第二个参数表示是否需要初始化类。源码中设置为 true, 因此 Class.forName 获取到 Class 对象时, 会自动对类进行初始化的。并且 Class.forName 加载类的 ClassLoader 和调用 Class.forName 所在的类的 ClassLoader 相同。上面的代码中, Class.forName("com.xttblog.Xttblog") 的调用会触发 Xttblog 的静态代码块的执行, 而 ClassLoader.getSystemClassLoader().loadClass("com.xttblog.Xttblog") 并不会。

我们知道 Spring 的 IOC 中有一个懒加载(延迟加载),如果你使用了 Class.forName,那么懒加载这个功能就无法实现了。Spring IoC 为了加快初始化速度,因此大量使用了延时加载技术。而使用 classloader 不需要执行类中的初始化代码,可以加快加载速度,把类的初始化工作留到实际使用到这个类的时候。

所以,Spring IOC 容器并没有采用 Class.forName 来加载类。

Spring IOC 容器为什么不使用 Class.forName 加载类

10T技术资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,GO等等。在公众号内回复对应关键字或框架名字,即可免费获取!!

 你再主动一点点 Spring IOC 容器为什么不使用 Class.forName 加载类  我们就有故事了

相关文章: