Spring-Core

spring-core模块笔记,主要从包模块拆开看的,类太多了,有些比较常用的类直接列出功能方便使用

annotation支持

@AliasFor别名注解,用于进行注解的属性值起别名与注解的属性覆盖等,spring本身大量使用,最直观的感觉是注解属性好像能继承一样

AnnotatedElementUtils:支持注解属性的覆盖(这个工具类产生的结果是全面支持@AliasFor的功能的,它支持了属性覆盖,借助AnnotationUtils.synthesizeAnnotation支持了别名)
getXXX(在当前类和注解层次上进行搜索),findXXX(除getXXX支持外还在接口/继承体系上进行搜索,所以推荐使用这个,比如findMergedAnnotation)

AnnotationUtils:基本注解工具,也有getXXX和findXXX和AnnotatedElementUtils语义类似,只不过不支持属性覆盖(它和AnnotatedElementUtils唯一的区别就是不支持属性覆盖而已,其他都支持,比如别名,相当于支持了一部分@AliasFor的功能,就是没有支持annotation这个方法而已).
synthesizeAnnotation提供了一些合成注解的功能,(实际上@AliasFor别名的功能是在这里实现的,在访问注解属性时它通过动态代理进行判断这个方法有没有别名,进而取出别名的值进行返回,具体的可以看这个链接https://www.jianshu.com/p/869ed7037833)

convert类型转换

spring中所有类型进行转换的实现A—>B
转换逻辑相对简单,有Converter接口匹配原类与目标类匹配,其次还有条件匹配ConditionalConverter转换.
通过ConfigurableConversionService接口(实现类为DefaultConversionService)管理Converter与ConditionalConverter.同时统一对外提供服务注册,转换等功能.
典型的如springmvc的类型转换就是通过这套机制实现的.

Env环境&配置

核心接口/类关系

PropertySource/MapPropertySource/PropertiesPropertySource 这是一个配置源的抽象
PropertySources/MutablePropertySources 这是一组配置源的抽象
PropertyResolver 这是配置解析定义,它被分化为两部分
Environment/AbstractEnvironment/StandardEnvironment 这是环境定义体系
ConfigurablePropertyResolver/AbstractPropertyResolver/PropertySourcesPropertyResolver 这是配置解析的体系

注意点就是环境和配置的概念是隔离的,他俩在实现上完全没有任何交集
实际上环境也只是配置文件中的一个参数,而这个参数比较特殊,key是指定的,我们称这个key所获得的value值为为环境

Serializer

这里看到的只是定义了serializer和deserializer接口,然后默认实现是使用的jdk的ObjectInputStream和ObjectOutputStream序列化实现的

Style

这个风格是指toString的风格,是自定义toString的一些信息,规范了spring内部的toString样式(搜索了一下适用范围,发现只有写测试用例的时候在用它打印一些参数与返回值信息...).它的核心实现是通过ToStringCreator这个工具类实现的,其他几个接口都是一些功能抽象与委托实现.

目前使用的较多的是apache的commons.long3包ToStringBuilder工具类,这个看起来更适合在类内部自己用

Task

TaskExecutor类似于Executor,实际上要早于它.它的实现有SyncTaskExecutor同步直接调用与AsyncTaskExecutor和AsyncListenableTaskExecutor作为异步接口的拓展最终由SimpleAsyncTaskExecutor提供实现,它内部即支持了限流器,也支持了ThreadFactory线程池,异步Feture通过FutureTask进行实现返回的.监听则是通过ListenableFutureTask继承自FutureTask然后重写了done方法进行回调success与failure监听.

IO资源抽象

Resource 资源的抽象(主要提供转换为InputStream的能力,比如常见的ClassPathResource)
ResourceLoader 对于资源加载能力的抽象(就是如何找到资源,主要提供查找对应的Resource)

Type

这部分还是很重要的,spring的加载元信息都在这里实现,分为三部分

1元信息
ClassMetadata-类元信息接口
MethodMetadata-方法元信息接口
AnnotationMetadata-带注解的类的元信息(方便获取类上的注解信息)接口
实际上这些元信息如果要加载再获取的话就没价值了,后面再MetadataReader的实现类SimpleMetadataReader中会通过AnnotationMetadataReadingVisitor访问者进行分析class字节码信息获取这些元信息,也就是不加载class但是分析class获取信息.

2元信息获取能力
主要是通过ResourceLoader(DefaultResourceLoader实例)获取Resource,并且通过分析Resource进而获取元信息实例
MetadataReader-持有Resource后进行分析字节码获取元信息
MetadataReaderFactory-一般情况全局对象,用于产生MetadataReader实例以及缓存
实际上可以将MetadataReader看成是元信息的上下文,它持有所有的ClassMetadata与AnnotationMetadata.也就是将Metadata又向上抽象了一层

3元信息匹配过滤器
TypeFilter-针对MetadataReader进行一些条件过滤,
常见的实例有AnnotationTypeFilter(通过匹配注解过滤),RegexPatternTypeFilter(通过全类名的正则匹配过滤)
实际用的地方非常多,因为加载之后需要过滤才是自己希望要的,一般情况都是注解过滤,也就是AnnotationTypeFilter这个类

结合ResourceLoader串起来看一下

分开看这三部分好像没什么关系,实际上列一下扫描实现的流程就能明白他们之间的关系了(扫描类代码看ClassPathBeanDefinitionScanner的scan方法跟踪)

ClassPathBeanDefinitionScanner的scan方法

这样一看就能看出来他们的关系了,从ResourceLoader加载Resource实例,然后通过MetadataReaderFactory换取MetadataReader,然后在BeanDefinition中提供分析,也就是为什么此时bean并没有被加载,反而就可以分析啦,实际上是分析的字节码信息获取的.

Core

AliasRegistry-别名注册表的顶层接口/SimpleAliasRegistry简单map实现类

AttributeAccessor-属性访问器的顶层接口-AttributeAccessorSupport简单的用Map存储实现

Constants-对static final方法的反射访问封装

Conventions-提供框架内部的各种命名.比如参数命名,返回值命名

DecoratingClassLoader/OverridingClassLoader-ClassLoader增加了排除与添加包路径功能的基础拓展

ParameterNameDiscoverer-参数名发现者,这个功能有时候还是能够用到的,其中比较常见的实现是LocalVariableTableParameterNameDiscoverer,通过解析字节码信息获取参数名

ExceptionDepthComparator-异常深度比较器.其中findClosestMatch静态方法直接使用即可比较一组异常中对目标异常最接近的异常,这是mvc全局异常进行选择对比的实现部分

MethodClassKey-method+object作为一个唯一的key,用于一般的指定对象与方法的调用结果缓存.并且实现了Comparable比较器

MethodIntrospector-提供一些Method的查询/过滤

MethodParameter-方法/构造函数与参数组成的一个Helper类

NamedThreadLocal/NamedInheritableThreadLocal-ThreadLocal和InheritableThreadLocal的可命名子类

OrderComparator-Spring内部的排序器.主要是PriorityOrdered最先升序,其次Ordered升序,其他都是最低.spring-web的拦截器顺序就是通过它排序的

AnnotationAwareOrderComparator-支持注解和接口混合的排序器,sort静态方法直接使用,内部使用较多

ResolvableType-对Field,Method,Class进行封装便于操作反射api

SerializableTypeWrapper-对于Field,MethodParameter,Class的序列化包装类

Util

简单设计/拓展-还有一些拓展在其他模块中,这里不列
backoff包-一个可重试的计数器,默认实现有乘数增长型ExponentialBackOff和固定增长型FixedBackOff

comparator包-很多比较器的实现包

concurrent包-模仿guava的ListenableFuture,实现类增强了FutureTask,提供Future的完成方法监听支持.在1.8中基本可以被CompletableFuture类替代了

IdGenerator-ID生成器实现的有JdkIdGenerator/AlternativeJdkIdGenerator/SimpleIdGenerator

PathMatcher-AntPathMatcher,Ant风格的路径匹配器,非常常用,简单的规则有"?一个字符,多个字符,*多级目录"

AutoPopulatingList-通过委托ArrayList实现了List,区别是get(index)的时候如果获取为null,那么会自动的通过反射新建对象填充并返回,好像没什么用

ConcurrencyThrottleSupport-简单的限流器支持,它的使用在SimpleAsyncTaskExecutor这个异步执行器执行时的限流选项

ConcurrentReferenceHashMap-使用soft/weak引用了key和value的ConcurrentHashMap

CustomizableThreadCreator-自定义一些线程信息.比如线程名,是否守护线程

PropertiesPersister-对Properties对象操作的一层委托封装

InstanceFilter-实例过滤器.在集合中匹配过滤对象,子类可以拓展实际匹配方法.比如ExceptionTypeFilter类,拓展的是异常类为子类就算是匹配了

MultiValueMap-一键多值的映射(Key-List<V>).实现的有LinkedMultiValueMap(委托ListedHashMap)

MethodInvoker-辅助性质的方法调用

MimeType/MimeTypeUtils-MimeType基本可以看做Content-Type.比如下面的图


Content-Type

PropertyPlaceholderHelper-占位符替换,用的非常多

StopWatch-简单的计时对象-一般用于开发测试中

StringValueResolver-String值解析器,常见的有PlaceholderResolvingStringValueResolver/EmbeddedValueResolver适配BeanExpressionResolver

纯工具类-杂项,框架内部使用居多

Assert-断言工具类

Base64Utils-可以使用jdk自带的Base64工具类

DigestUtils-摘要工具类.比如md5摘要,sha256摘要等操作或者使用guava的Hashing(推荐),这个流式api用起来更爽快

StreamUtils-io工具.简单的copy操作工具.

FileCopyUtils-file copy顺便close掉io

FileSystemUtils-文件夹的递归删除和创建

ClassUtils-对于一些反射方法的封装,提供了很多对基础类型,代理,桥接方法等特殊方法的支持

ObjectUtils-对Object的工具提供.很多基础类型数组的HashCode支持

CollectionUtils-集合工具支持

NumberUtils-一些Number检查/转换

PatternMatchUtils-简单匹配器-xxx* *xxx xxx pattern styles.

ReflectionUtils-Spring中的反射工具类,比较常用

主要提供属性/方法的遍历,属性获取/方法调用(转换为运行期异常),常用Object中方法的判断
(isToStringMethod,isHashCodeMethod,isEqualsMethod,isObjectMethod…)
常用:
doWithXXX(递归遍历属性或方法) doWithLocalXXX(遍历本类的方法或属性)
getAllDeclaredMethods:递归遍历获取所有声明方法
invokeMethod,getField:将声明异常转为运行异常避免try-catch

ResourceUtils-做一些资源类型判断,加载文件操作

SerializationUtils-jdk的serialize/deserialize方法

SocketUtils-查找可用的tcp/udp端口

StringUtils-简单的String功能,以及String数组的功能StringUtils.tokenizeToStringArray这个分割字符串的方法比较厉害,可以传入多个分隔符

SystemPropertyUtils-提供占位符的形式(${env.key:defaultValue})替换为System.getProperty的值

这么多基础工具类一部分是为了自定义错误信息输出,很多方法都是参数判空,然后反射方法调用,出错了可以自定义为框架错误输出


总结

1很多管理器职责在命名上都抽象出了新的概念从而从新命名了.打破了各种XXX-Manager这样的命名,也就是根据实际用途将这种管理器命名为xxx解析器,xxx注册器,xxx加载器,xxx工厂,将Manager的功能命名化,突出概念

2功能抽象的很细致.像Environment还专门会有一个ConfigurableEnvironment继承它来提供Environment的写入/修改能力

3包装类(装饰者模式)用的很多.比如说有一些后置操作,增强操作,那就包装一层.对原代码无侵入,内部实现也好看一些

4经常是双接口演化,分别演进到不同的接口,然后下层到实现类时采用继承/委托将此功能撇到别的类中实现

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • 概述 org.springframework.context.ApplicationContext接口是Sprin...
    0d1b415a365b阅读 5,465评论 1 3
  • bean: 应用里被Spring IoC容器管理的对象叫做bean.Spring IoC容器负责bean的初始化,...
    竹天亮阅读 669评论 0 1
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,865评论 6 13
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,423评论 0 4
  • 可见性: 一个线程对共享变量值的修改,能够及时地被其他线程看到。 共享变量: 如果一个变量在多个线程的工作内存中都...
    OmaiMoon阅读 190评论 0 0