”命名和缓存失效是计算机科学里面最难应对的两件事“
1. 前言
无数前辈告诉我们要去读源码,理解里面的思想,设计理念,解决问题的方法等等。本人愚笨,只在转了Java之后才正式开始看源码(之前做WPF开发时看个源码费劲死了;最要命的是本人做不到运行时调试源码,导致查找问题特别费劲。尤其当时一直单打独斗,问人是别想了,搜索引擎之下始终无法成功。)
在近两年阅读源码经历中,除了感慨源码的精妙外,还对其中的命名颇为赞同,觉得大有学习的必要。断断续续地整理了一份清单。现在将它公布出来,非常欢迎补充和指正。
有些地方的时间注解我故意没有去掉,也是为了时刻提醒自己这些内容需要不断打磨。
废话不多说,让我们直接开始吧。
2. 正文
2.1. getConnectionDirect
方法名
- 来源于druid源码中的
DruidDataSource
类。 - 这命名一看就知道是最终干活的方法,而不是将任务分发出去的调度方法,在这个方法里一定能看到最终的实现逻辑。
- 类似的还有Spring源码随处可以见的
doXXXX
方法。
2.2. doGetBean
方法名
- 来源于Spring源码中的
AbstractBeanFactory
类。 - 这命名一看就知道是最终干活的方法,而不是将任务分发出去的调度方法,在这个方法里一定能看到最终的实现逻辑。而与之相对应的
GetBean
则是分发任务的方法了。 - 类似的就是druid源码中的
xXXXXDirect
方法。 - 2017/6/23 终于理解了为啥名为
doXxx
的方法有时会被作为public访问级别。因为此时你是需要将整个逻辑控制权都交由调用者. 框架只负责流程顺序的组织和推动。强大的管道式处理,stream !
2.3. innerGetXXX
方法名
- 这个忘记哪看来的了。
- 这命名也是最终干活的方法.与之对应的
getXXX
就是分发任务的方法了。
2.4. DruidConnectionHolder
类名
- 来源于druid。
- 类似于Spring里的
BeanDefinitionHolder
类。 相似的还有mybatis-spring-xxx.jar中的SqlSessionHolder
类。 - 看名称就知道内部持有一个
DruidConnection
实例。但因为引入了该中间层,所以程序有了更高的灵活性。
2.5. callResultHandler
方法名
- 来源于Mybatis中的
FastResultSetHandler
类 。 - 看名称大概就能猜到会调用
ResultHandler
接口里的处理方法;这种名称在接口只有一个方法时更显著;而ResultHandler
接口正好就只有一个方法。
2.6. ResultMapResolver
类名
- 来源于Mybatis 。
- 该类的构造函数接收一堆参数,并通过向外暴露的
resolve
方法返回一个ResultMap
实例。 - 类名就很清晰表示是用来检索一个
ResultMap
。 - 将检索出
ResultMap
的逻辑封装进这个ResultMapResolver
类中。 - 在构造函数中传入足够的信息, 最终在
resolve
方法中返回类名中的XxResolver中的Xx部分. - 封装的是从传入的信息中检索出Xx的逻辑。
- 类似的还有Spring中的
NamespaceHandlerResolver
接口, 看名字就知道是用来检索NamespaceHandler
; 而NamespaceHandlerResolver
接口定义的方法也是只有一个resolve
方法。
2.7. TypeReference<T>
类名
- 来源于Mybatis 。
- 官方注释就是
References a generic type
。 - 用于引用一个泛型类型。
- Wrapper模式。
2.8. supportsEventType
方法名
- 来源于Spring源码中的
SmartApplicationListener
接口。 -
SmartApplicationListener
接口扩展自最基础的ApplicationListener
。增加了- 判断本listener支持该event type的
supportsEventType
方法; - 以及判断本listener支持该source type的
supportsSourceType
方法。
- 判断本listener支持该event type的
- 将判断的权限下放给各个listener,这样
ApplicationEventMulticaster
在广播事件时只需要简单的调用即可。 - 将决策权下放,而不是由管理类来决定调用哪些;是否响应该事件的权限被下放给了每个真正的处理者,由它们自己来决定自己是否处理这类事件。
- 类似的还有
org.springframework.web.servlet.HandlerAdapter
接口;该接口声明的supports
方法也是将决策权下放给每个HandlerAdapter
,让它们自己决定是否支持该handler。
2.9. HostConfig
类名
- 来源于Tomcat源码。
- 类似的还有Tomcat中的
HostConfig
,ContextConfig
,EngineConfig
,ApplicationFilterConfig
等。 - 专门针对某个容器类型的Config信息集结地。
- 类似的还有log4j2中的
LoggerConfig
,其专门针对log4j2.xml配置文件中的<Loggers>的配置信息。
2.10. getFacade
方法名
- 来源于Tomcat源码中的
ApplicationContext
类(注意这个ApplicationContext
类不是Spring中的那个接口)。 - 获取本类的装饰器类型的实例。
- 这样
ApplicationContext
和其门面模式ApplicationContextFacade
相互知道; 而不是仅仅ApplicationContextFacade
知道ApplicationContext
。
2.11. ProxyDirContext
类
- 来源于Tomcat源码。
- 注意这名字就这样,并没写反。
- 该类直接继承自
DirContext
,看名字应该就是做了DirContext的代理。 - 而这个类的真正用途是作为Tomcat所读取到的静态资源载体的
FileDirContext
或WARDirContext
统一对外表现形式;而且因为多了这个中间层,所以给予后期的需求变更带来极大的弹性。 - 类似的还有Mybatis中的t
MixedSqlNodet
类,内部定义的SqlNode实现类最终都是以MixedSqlNode
形式向外暴露,这样就统一了门面。
2.12. stopInternal
方法名
- 来源于Tomcat源码中的
LifecycleBase
类。 - 这个一看就是在内部使用的方法,类似的还有
destroyInternal
,initInternal
,startInternal
等。 - 和上面的`innerGetXXX 类同。
2.13. DocumentVisitor
类名
- 来源于aspose.words源码。
- 看名字就知道是对应于Document的.
- 而
Document
有一个名为accept(DocumentVisitor visitor)
的方法;通过accept
方法,将暴露Document内部状态的操作交给专门的DocumentVisitor
类,而不是将Document
内部状态信息直接公开化。 - 也是非常典型的Visitor模式了。
2.14. Parameters
类名
- 来源于apache.commons.configuration2 源码。
- 这个类位于fluent 包下, 流式操作。
- 可以发现fluent 包下的类都是这个模式。
2.15. TriggeringPolicy
接口名
- 来源于log4j2源码。
- 策略模式。相应的实现类有
OnStartupTriggeringPolicy
,SizeBasedTriggeringPolicy
,TimeBasedTriggeringPolicy
,CronTriggeringPolicy
等;以及代表多种Policy组合的CompositeTriggeringPolicy
。
2.16. newDocumentBuilder
方法名
- 来源于log4j2源码中的
XmlConfiguration
类。 - 实例化一个
DocumentBuilder
对象。
2.17. ContextSelector
接口名
- 来源于log4j2源码。
- 一看名字就是封装了筛选出某个Context的逻辑。
- 依然是策略模式。
2.18. ScriptManager
方法名
- 来源于log4j2源码。
- Factory的另外一个名字。
2.19. CompositeTriggeringPolicy
类名
- 来源于log4j2源码。
- 组合模式, 类似的还有Mybatis里的
MixedSqlNode
; log4j2的CompositeFilter
;Spring-web中的CompositeFilter
; Tomcat中的CombinedRealm
。
2.20. ClassFinder
方法名
- 来源于struts2源码xwork-core-version.jar。
- 一看就是用来封装查找某些事物的逻辑。
- 类似的就是上面的
ContextSelector
接口名。
2.21. FormatProcess
类名
- 来源于hibernate。
- 封装了进行格式化处理的逻辑。FormatProcess就这个命名而言,签名的Format为名称,后面的Process为动词。
- http://zjfhw.iteye.com/blog/2062213
2.22. Lifecycle
接口名
- 来源于Spring源码中的spring-context-version.jar -
org.springframework.context.Lifecycle
- 非常关键的一个接口;Tomcat,logback,log4j2,log4j,jetty中均有同名的接口。区别就是Life后的那个C是否大写。
- 一个框架自身启动时,必然涉及到内部逻辑,再考虑到外部扩展也需要在启动时进行某些自定义操作,所以自然而然提供了这个接口来将外部扩展的自定启动逻辑并入进来。
2.23. ObjectListing
类名
- 来源于 aliyun-sdk-oss-version.jar。
- 一看类名字就知道其中存放的是一组Object.
2.24. ObjectMetadata
类名
- 来源于aliyun-sdk-oss-version.jar。
- 看名称就知道其中存放着关于什么的元数据(元数据是关于数据的数据)。
- 类似的还有Spring中的
ClassMetadata
接口,MethodMetadata
接口。AnnotationMetadata
接口等; 以及Dom4j里的BeanMetadata
。
2.25. ManifestResourceTransformer
类名
- 来源于maven源码中的
org.apache.maven.plugins.shade.resource.ManifestResourceTransformer
。 - 负责转换
ManifestResource
。主要是学习下人家的这流处理, 预留出一个<Transformers>标签, 就不信还有翻天的自定义需求。
2.27. doesObjectExist
方法名
- 来源于 aliyun-sdk-oss-version.jar中的
OSSClient
类中。 - 用于判断是否存在xxx。
2.28. listObjects
方法名
- 来源于aliyun-sdk-oss-version.jar中的
OSSClient
类中。 - 列出xxx。
- 阿里的规范里已有类似的建议。
2.29. setHandled
方法名
- 来源于jetty中的
org.eclipse.jetty.server.Request
类。 - 职责链的每个成员通过调用这个方法来选择将执行逻辑进行下去, 如果设置为true, 则代表职责链的执行到此为止,链条里剩下的元素不再执行。
- 类似的还有WPF中路由事件响应函数里的
e.Handled=true
,以及SpringMVC中的ModelAndViewContainer.setRequestHandled(true)
。
2.30. ApplicationEventPublisher
接口名
- 来源于Spring源码中的
org.springframework.context.ApplicationEventPublisher
接口。 - 将事件播放的职责转移给专门的类去处理。
2.31. Wrapper
接口名
- 来源于JDK源码中的
java.sql.Wrapper
接口。 - wrapper模式。
- 提供了两个方法:
- unwrap
- isWrapperFor
- 类似的还有Mybatis源码中的ClassLoaderWrapper类。
2.32. RoutingStatementHandler
方法名
- 来源于Mybatis源码。
- 构造函数就是根据条件对内部的
delegate
字段进行赋值。 - 内部并没有实际的执行逻辑;只是将逻辑进行分发。
RoutingStatementHandler
类实现的接口类型和内部的delegate
字段的类型都是StatementHandler
。 - 类似的还有spring-jdbc中的
AbstractRoutingDataSource
类
2.33. DataSourceLookup
接口名
- 来源于spring-jdbc源码。
- 一看就是来找
DataSource
的。 - 类似的有上面提到的
ContextSelector
,ClassFinder
。 - 类似的还有log4j-core-xxx.jar中名为lookup的顶级package; 以及 apache.commons.configuration2中的
Lookup
类。
2.34. setRole
方法名
- 来源于Spring源码中的
AbstractBeanDefinition
类。 - 注意是出现在
AbstractBeanDefinition
抽象类中, 而非BeanDefinition
接口中。 - 通过为
BeanDefinition
设置Role来进行某些优先级处理,差异化处理。
2.35. IHttpContextAccessor
接口名
- 来源于 asp.net core 中。
- 不直接操作HttpContext, 而是选择专门独立出一个类来进行读取写入操作. 原本的
HttpContext
应该只负责存储数据。 - 和上面的 Visitor非常类似。
2.36. Configurable
接口名
- 来源于 apache-commons.net
- 观察该接口的唯一方法, 只有一个
void configure(FTPClientConfig config)
; 注意其参数, 也就是说所有相关参数都在FTPClientConfig
中。 -
FTPClient
实现了这个接口, 通过实现接口方法, 可以获取到所有相关的参数。另外还可以利用该接口往FTPClientConfig
实例中注入参数。
2.37. PropertyEditorSupport
类名
- 来源于Spring。
- 实现了
PropertyEditor
接口。 - 不局限于命名为
AbstractPropertyEditor
。 - 类似的还有
ApplicationObjectSupport
类(spring-context-xx.jar, 该类实现了ApplicationContextAware
接口)。
2.38. RuleSet
接口名
- 来源于Digester源码。
- 官方注释为
represents a set of Rule objects
。 - 不仅仅有RuleCollection一种命名集合的方式。
2.39. ApplicationContextAware
接口名
- 来源于Spring源码。
- 如果发现所注册进来的bean实现了这个接口, 就将对应的实例(例如这里的
ApplicationContext
实例)利用该接口定义的方法将相应的实例注入到bean中。 - 类似httl等都有相关的应用。
- 另外注意在spring中,这些xxxAware都继承自
Aware
这个Marker Interface
。
2.40. Reconfigurable
接口名
- 来源于log4j2。
- 实现配置文件在运行时的刷新,
- 类似的命名还有Reloadable,AutoRefreshable接口( 自己想到的)。
2.41. ExtendedLogger
接口名
- 来源于log4j2-api-xx.jar。
- 扩展原有
Logger
接口, 不对现有的Logger
接口里进行扩展, 而是再新建一个接口ExtendedLogger
;典型的“对扩展开放, 对修改关闭”。
2.42. BeanDefinitionDefaults
类名
- 来源于spring-beans-xxx.jar。
- 保存一组
BeanDefinition
的默认值
2.43. RequestMappingInfo
类名
- 来源于spring-webmvc-xxx.jar。
- 一看名字就知道其内部存储了
RequestMapping
相关的一系列信息。
2.44. PatternsRequestCondition
类名
- 例子就是上面
RequestMappingInfo
类中的一系列PatternsRequestCondition
,RequestMethodsRequestCondition
类型字段。 - 其中存储了一系列条件。
2.45. SpringApplicationRunListeners
类名
- 来源于 Spring-boot。
- 其并没有继承自
List<SpringApplicationRunListener>
, 但看名字依然很容易望文生义。 - 注意这个类的访问级别属于package。
2.46. addToEnvironment
方法名
- 来源于SpringBoot中的
RandomValuePropertySource
类。 - 将自身加入到容器中,反客为主。
- 很多时候颠倒主从顺序会有惊喜,控制反转;类似的还有上面的
supports
方法。
2.47. Ordered
接口名
- 来源于spring-core-xxx.jar。
- 另外一个是2.5版本时加入
PriorityOrdered
标志性接口。 - 配合
OrderComparator
比较器; 排序操作非常easy。 -
OrderComparator
比较器进行排序的时候,若两个对象中有一个对象实现了PriorityOrdered
接口,那么这个对象的优先级更高;若两个对象都是PriorityOrdered
或Ordered
接口的实现类,那么比较Ordered
接口的getOrder
方法得到的值。值越低,优先级越高。
2.48. BeanPostProcessor
接口名
- 来源于Spring源码。
- 提供给外界的扩展,允许外部的介入——后置自定义处理。
- 类似的还是有Spring-session中的
RequestResponsePostProcessor
。
2.49. findParameterValue
方法名
- 来源于spring-mvc-xx.jar中的
org.springframework.web.util.WebUtils
类。 - 相比较
getXXX
,findXXX
更能体现可能找不到的情况。
2.50. InterceptorProvider
接口名
- 来源于cxf-core-xxx.jar。
- 其直接实现类为
AbstractBasicInterceptorProvider
, 为所有其他相关类的基类。 - 这也不失为一个好的方式,即提供一个专门的接口来专职提供各种拦截器。
2.51. javax.servlet.ServletRegistration.Dynamic
类名
- 来源与于 java-servlet3.0规范。
- 在
servletContext.addServlet("CXFServlet", org.apache.cxf.transport.servlet.CXFServlet.class)
之后返回的一个实例允许作更多的配置。
3. 结语
这注定是一篇无法完结的博文,未完待续!