准备工作:
1.选择一个好工具IDEA (eclipse 也可以,本文主要是以idea为例讲解)
DEBUG教程见:http://blog.csdn.net/qq_27093465/article/details/77449117
2.使用maven构建工程,并右键工程 down source 下载框架源码
知识准备:
1.了解常用设计模式:模板模式 、策略模式、代理模式(jdk内置的代理模式实现机制)、工厂模式、单体模式等等
2.UML类图和面向对象设计原则
SRP:单一职责原则。一个类应仅有一个改变的理由。
OCP:开闭原则。不应修改已有的类,而应扩展一个类。
LSP:里氏替换原则。子类对象能随时随地替换其超类。
ISP:接口分离原则。一个客户程序只需关注自己所需要的接口。
DIP:依赖倒置原则。依赖抽象而避免依赖细节
COC : 惯例优先原则 Convention Over Configuration
ps:
a.设计模式和UML类图,可以帮助理顺框架内部接口的调用关系,和接口的具体实现;
b.框架都是高度抽象的,直接看源码都是接口之间的调用;借助IEDA DEBUG功能,能快速找到具体的实现类;
如何跟踪框架源码?以springboot中使用security为例。
1.从配置基类WebSecurityConfigurerAdapter入手:
WebSecurityConfigurerAdapter
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN")
.and()
.withUser("test").password("password").roles("ADMIN");
auth.authenticationProvider(new UserSignAuthenticationProvider());
}
2. 查看类代码,并绘制UML类图 :
查看从AuthenticationManagerBuilder的注释,大概看一下注释中提到的类和接口,将其画到UML图中;
a.查看具体实现类,要避免陷入细节中去,一个具体实现类由大量的成员变量和方法构成,但要记住实现类是接口的实现,通常一个接口只做一件事而已(这个就是单一职责原则),重点看实现类如何实现接口方法,其他方法都是为接口方法实现服务的。
b.使用惯例优先原则,从类名来了解使用其使用到的设计模式,如AuthenticationManagerBuilder,Builder结尾的按惯例是表示生成器模式;这时就要对该模式有个大致的认识,该模式一般用于复杂对象的初始化。
生成器模式的介绍:http://blog.csdn.net/top_code/article/details/8469297
c.为了解耦和重用代码,通常是实现类实现接口时,通常会继承至一个抽象类(基类中包含公用代码),模板模式中会大量使用该技巧。
d.绘制UML图时,必须将接口的方法写上,因为是接口定义了框架的核心。基类上将抽象方法写上去。
看看AuthenticationManagerBuilder的类图结构,仔细观察UML标注出来的方法AuthenticationManagerBuilder如何实现的,很容易看出 AuthenticationManagerBuilder最终会生成ProviderManager。另外一个类似的接口实现 HttpSecurity HttpSecurity 会生成 DefaultSecurityFilterChain 。
3.通过步骤2,我们了解到配置最终会生成ProviderManager 和 DefaultSecurityFilterChain ,这两个类肯定是非常有用的,这时我们可以在ProviderManager的接口定义方法和构造方法上打上断点,因为接口上的方法是重点,构造方法能找到实现接口所依赖的其他类,其他定义的方法都是为该方法服务的。
4.运行起来,我们可以看到ProviderManager初始化的过程,我们会看到实际初始化时会用到哪些类,将它在UML画出来,并标注成红色,因为这些类是框架接口的默认实现类。
5.从第4步开始,可以开始向下找ProviderManager依赖了哪些类来实现接口定义的方法。还可以向上找到哪些类调用了ProviderManager,怎么找?使用IDEA找接口方法被哪些类调用,Find Usages 。
从上面看到UsernamePasswordAuthenticationFilter有调用接口方法,右键Jump to Type Source ,看看如何调用的。
到这里,大部分搞J2EE开发的就比较熟悉啦。从request中获取用户名密码,然后交给AuthenticationManager进行验证。
重复4,5两个步骤,打断点找到接口的具体实现,find useage 查找类如何被其他类依赖使用,整个的框架逻辑就出来啦。
总结:
1.从配置文件,配置类找到切入点;切入点通常是一个类,不是一个接口。画出类和接口之间的类图,找到类的核心方法(即实现的接口方法)
2.以切入点为据点,向上查找调用者,向下查找被调用者;调用链条慢慢就浮现啦。
3.然后再将链条上关键的接口找出来,找出它的实现类,借助UML图,整个框架的概貌就出来啦。
4.对设计模式的熟悉程度,和扎实的OO基础有助于快速理解框架作者的编码意图,更好的阅读代码。如果没有这样的基础,阅读代码就会很费力。
5.好的开源框架命名很规范,遵循惯例优先原则,看看类名基本上就能知道使用的设计模式是什么。有了设计模式,基本上就能猜到作者会去怎么写代码了。还是第4点,设计模式其实就类似与中国功夫里的拳法套路。
---------------------
版权声明:本文为CSDN博主「json20080301」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/json20080301/article/details/79346569