Spring AOP IOC 之外 —— 类的命名

规范命名,有助于思想的传承。

最近在阅读Spring的过程中,发现除了 AOPIOC之外,还有许多被忽略的有助于阅读/理解源码的点,在此一一做笔记,供人参阅,希望有所帮助。如有错漏,希望能够指出以便修正,不胜感激。

Spring 的源码中,核心类的命名与功能划分具有一定的规范,了解后,在阅读Spring源码中,有些许的帮助。

幂等与非幂等/读写分离

Spring底层核心类,很多接口是按照幂等与非幂等/读写分离进行划分的:

BeanFactory:内部方法均为获取或者判断的方法,如: getBean
, containsBean
等;

ConfigurableBeanFactory
:继承了 BeanFactory
后,内部定义了属性设置的入口,非幂等的,如: setParentBeanFactory
setConversionService

Environment:内部方法均为获取,或者判断的方法,如: containsProperty
getActiveProfiles

ConfigurableEnvironment:继承了 Environment
后,内部方法定义的是设置方法,非幂等的,如: setActiveProfiles
merge

命名习惯01

Spring 的 接口定义中,接口的命名有其规范性存在,
单纯的幂等性方法,直接按实际作用命名(主要为幂等性),
非幂等性,则在实际作用命名前(继承了幂等性类),增加 `Configurable`,
基础实现,则在非幂等性的基础上(继承了非幂等性类),对方法进行通用的基础实现

Environment:拥有获取 property
profile
的方法

ConfigurableEnvironment:拥有 setActiveProfiles
等方法

AbstractEnvironment:对以上两个类方法进行基础实现

ApplicationContext:拥有获取 ID
BeanFactory
等方法,如: getApplicationName
getParent
getAutowireCapableBeanFactory


ConfigurableApplicationContext
:拥有设置对应属性的方法,如: setEnvironment
setParent


AbstractApplicationContext
:对上述两个类方法进行基础实现

PropertyResolver:获取属性的方法,如: getProperty
containsProperty


ConfigurablePropertyResolver
:设置性的方法,如: setConversionService
setPlaceholderPrefix


AbstractPropertyResolver
:对以上两个类方法继续基础实现

PropertyAccessor:属性的判断及获取

ConfigurablePropertyAccessor:属性的设置

AbstractPropertyAccessor:基本实现

命名习惯02

针对向某个 Collection 中添加/注册某个实例,Spring 常用的命名方式是使用 Registry 作为后缀,就实际功能而言,这些类是将对应实例纳入Spring容器管理的入口!

ConverterRegistry:转换器注册器,提供了 addConverter
addConverterFactory
等方法

AliasRegistry
:别名注册器, registerAlias
removeAlias
isAlias
getAliases


BeanDefinitionRegistry
:Bean定义注册器,提供了 registerBeanDefinition
removeBeanDefinition

SingletonBeanRegistry:单例注册器,方法: registerSingleton
containsSingleton

命名习惯03

默认实现,在Abstract***之后,使用了Default前缀

如: DefaultConversionService
DefaultListableBeanFactory
DefaultNamespaceHandlerResolver

命名习惯04

当一个类会层级概念(表明该类在处理时需要考虑父级情况)时,会定义一个前缀:`HierarchicalXxx` 的类,这个类内部的方法会涉及到:`setParent`,`getParent`,如:

HierarchicalBeanFactory:有内部方法, getParent
containsLocalBean


HierarchicalMessageSource
:有内部方法, setParentMessageSource
getParentMessageSource

命名习惯05

对于加载的命名,使用的是 `XxxLoader`,如:

ContextLoader:上下文加载( web
应用的时候)

ResourceLoader:资源加载的时候

DocumentLoader:加载 XML
文档

总结上述,掌握了Spring的命名规范后(实际只在核心功能类——基础context/beanfactory 中常见,后续其他类命名未见强制以上规范),在阅读源码过程中,就不会因为各种命名导致思绪混乱,比如:

看到 ConfigurableXxx
的类,就知道它是主管设置的入口,看到 getParent
,就知道对应的类应该是继承了 HierarchicalXxx

如:在 AbstractBeanFactory
方法: getMergedBeanDefinition
中,有如下一段代码,在进行分析的过程中,依据命名规范,我们可以比较清晰地理解获取过程

try {
    parentBeanName = transformedBeanName(bd.getParentName());
    if (!beanName.equals(parentBeanName)) {
        // 递归获取合并后的父定义,出口是:getParentName == null (即上述 if)
        pbd = getMergedBeanDefinition(parentBeanName);
    }
    else {        
        // 这里处理的情况是,子 beanName 与 父 beanName 相同!
        // 在一般情况下,如果我们在同一个 xml 文件中,定义了两个相同的 beanName,是会抛异常的,
        // 但这里却有处理 beanName 相同的情况
        // 此时就需要回顾,BeanFactory 有子类 HierarchicalBeanFactory,这种工厂具有层级关系,
        // 而 BeanName 可以相同,且 beanName 分属父子,而在同一层级的 BeanFactory,即使父子关系,同名也会异常
        // 所以,这里就需要上溯父级工厂,去父级工厂就行递归 parentName 的 Bean定义(只有在父级工厂,才允许由相同名称的 beanName)
        // 而父级工厂为什么要判断是 ConfigurableBeanFactory 呢?
        // 因为 beanName 的设置入口,由 ConfigurableBeanFactory 提供,如果不是此种类型,那在 Spring 体系中,是不允许的(不规范的)
        BeanFactory parent = getParentBeanFactory();
        if (parent instanceof ConfigurableBeanFactory) {
            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);    // 从父工厂开始继续递归 Bean定义
        }
        else {
            throw new NoSuchBeanDefinitionException(parentBeanName,
                    "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                    "': cannot be resolved without a ConfigurableBeanFactory parent");
        }
    }
}
再,我们平时的使用中,常常会执行 (BeanFactory)ApplicationContext

来强转并使用 BeanFactory
的方法 getBean
获取单例,就规范而言,是因为 BeanFactory
是作为获取的入口。

常见的继承关系有:

DefaultXxx
–> 继承 AbstractXxx
–> 继承 ConfigurableXxx
–> Xxx

这样,最终子类将拥有设置与获取的方法。

了解一些命名约束,有助于更好地理解源码本义,以上均为个人阅后感,如有错误,还请指正。

原文 

https://segmentfault.com/a/1190000022656576

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring AOP IOC 之外 —— 类的命名

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址