更新:Spring源码编译
前言
看了很久才敢动键盘,怕写的不好,写的不清楚。但现在写也不是说能写好了,搞清楚了,而是我明白如果不写,这道坎就迈不过。有些问题就不会去钻研深究。另外,Spring源码实在是太庞大了,我满怀信心的从官网Fork了一份,然后Clone到本地,坚信我能干翻Spring源码,但用IDEA打开的时候,居然直接把我的IDEA给干翻了,导致我看Spring源码得关掉其他一些应用,否则卡的怀疑人生。
为什么读源码?
这个很重要,否则你会坚持不下去,会放弃,所以目标很重要,我读它的目的是:
- 面试,跟之前看MyBatis不一样,读Spring是为了面试做准备,可以说非常功利心了
- 原理,工作两年发现只会用,虽然之前看过一些,但总觉得不成体系,有点焦虑
- 虽然是在第三条,但是非常重要,了解它的思想体系,学习它的面向对象设计
阅读的一些心得
分享一些心得,但不一定有用,但是我本人的最佳实践:
- 多看别人的文章,因为他们真的写的很好好好好好好好好好好!
- 耐心!耐心耐心!耐心耐心耐心!如果非要说个要求的话,这是唯一一个要具备的能力
- 跟阅读MyBatis源码一样,分模块阅读,先找主线,忽略细节,理清整体脉络
- 看的时候不妨YY一下,如果是你你会怎么设计?大佬们为什么要这么设计?
- 目前为止,我看了很多别人的文章,源码Debug了好多次,所以十几次不行,我都觉得是正常
源码分析
基本概念
IoC
Inverse of Control,控制反转。原来是由程序员来创建对象控制它的生命周期等,现在把对象的创建权利反转给了Spring
DI
Dependency Injection,依赖注入。当Spring创建好Bean对象时,动态的将依赖对象注入到Bean组件中
一个简单的Demo
Java代码
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-ioc.xml");
// 这个bean从xml中获取
StudentA studentA = (StudentA) context.getBean("studentA");
// 输出:cn.eleven.springcyclic.v2.StudentA@64bfbc86
System.out.println(studentA);
// 这个bean通过注解扫描获取
Object studentB = context.getBean("studentB");
// 输出:studentB: cn.eleven.springcyclic.v2.aware.StudentB@67b467e9
System.out.println("studentB: " + studentB);
}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<!--注解扫描-->
<context:component-scan base-package="cn.eleven.springcyclic.v2.aware"/>
<!--xml配置-->
<bean id="studentA" class="cn.eleven.springcyclic.v2.StudentA" >
</bean>
</beans>
注解声明
@Component
public class StudentB {
}
上面两种是使用时用的较多的,一种是通过加载xml配置,一种是扫描注解,目的都是一样,将该对象托付给Spring容器管理,而我们要研究的是Spring实现这一过程的
BeanFactory体系结构
我们先不急着Debug深入源码深处,先看下Spring几个重要接口的体系架构
BeanFactory
它是Spring bean容器最顶级接口,它有令人眼花缭乱的子类,但是它自己却很简单,只定义了几个bean相关的方法,例如上面Demo演示的getBean()方法,下面的几个接口都是对它的扩展(接口隔离原则)**。**我们称它为一级接口。
HierarchicalBeanFactory、ListableBeanFactory、AutowireCapableBeanFactory
ListableBeanFactory:不需要by name一个个查找,可以一次性获取所有Bean
AutowireCapableBeanFactory:提供装配功能
HierarchicalBeanFactory:提供访问父容器的功能
我们称它们是二级接口
ConfigurableBeanFactory
提供了配置容器的功能,我们称它为三级接口。
ConfigurableListableBeanFactory
定义了bean一些操作,重要的是它的子类是DefaultListableBeanFactory,是BeanFactory们的默认实现
BeanDefinition
类如其名,它描述一个类实例信息
ApplicationContext体系结构
应用上下文,最主要的作用是为Spring提供了共享的Bean环境。把它和上面的类图连起来看看,看到最底下的ClassPathXmlApplicationContext类,我们上的demo中通过它来加载xml配置文件
小结
本文介绍了Spring IoC、DI几个重要接口的体系结构,BeanFactory容器、BeanDefinition描述类实例的信息、ApplicationContext为Spring提供了一个共享的Bean环境。还是开头所说,先了解下大概,是个什么玩意儿,下一篇我们就深入腹地,一步一步Debug源码。
参考资料
- litespring,公众号【码农翻身】,巨佬,手摸手带你写轻量级Spring,视频是收费的,但是万能的B站有
- 都说写博客抄来抄去,但其实抄的都是它:《Spring揭秘》
- 公众号【芋道源码】,大佬,源码系列非常强悍
- 本文中演示的demo仓库
请你相信我所说的都是错的