Spring学习--SpringCore包的结构和主要功能

作者: followtry | 2021-05-07 | 阅读
「编辑」 「本文源码」

主要功能

Spring-core内都是基础通用的功能,不涉及到Spring的IOC等概念。

主要目录功能包括

  1. ASM: 对ASM7.x功能的重新打包,避免应用级的ASM的依赖和任何潜在冲突。
  2. cglib:对CGlib核心包的重新打包,仅限于Spring内部使用
  3. core.annotation: 注解,元注解,属性覆盖合并注解的核心支持包
  4. core.codec: 在字节流和java对账建进行转换的Encoder和Decoder抽象及具体实现
  5. core.convert: 不同类型间的转换器
  6. core.env: Spring的环境抽象和对分成属性源的支持
  7. core.io: 用于处理字节缓冲区实现的通用抽象
  8. core.log: 对于一系列Log的代理和包装
  9. core.serializer: 序列化和反序列化相关的接口及实现类
  10. core.task: 定义了spring的任务执行器的抽象,并提供同步任务执行器SyncTaskExecutor和简单的异步任务执行器SimpleAsyncTaskExecutor的实现
  11. core.type: 类型自省的核心支持包
  12. core: 提供用于异常处理和版本检测的基本类,以及其他不特定于框架任何部分的核心帮助程序。
  13. lang: 提供语言级别羽翼的通用的注解,在框架代码库中的描述性使用,可以被构建工具或者IDE识别验证。
  14. objenesis: spring对objenesis的重新打包,避免与三方包和依赖的潜在冲突
  15. utils: spring的基础工具包,主要报错编码,类,集合,数值,问津系统,id生成器,网络IO等的工具类
  16. utils.backoff: 一种通用的退避抽象。
  17. utils.comparator:比较器及实现类,比如可逆比较器和复合比较器
  18. utils.concurrent: future扩展相关的适配器和回调等类
  19. utils.function: Supplier的单例工具类
  20. utils.unit: 数据单位转换。B,KB,MB,GB,TB等
  21. utils.xml: xml的解析和转换的工具类

core.serializer 包

接口为DeserializerSerializer,分别是反序列化和序列化的策略接口。用于进行Java对象和输入输出流之间的转换

Serializer实现类

DefaultSerializer

该类为Serializer接口的默认实现类,功能就是将java对象转为Output流。核心代码如下

//直接使用ObjectOutputStream将java的Obj抓换,当然在转换前需要实现Serializable接口
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(object);
objectOutputStream.flush();

SerializingConverter

该类为Serializer的代理类,用来将java Object转换为Byte的字节数组。而使用的转换器就是DefaultSerializer

Deserializer实现类

DefaultDeserializer

该类为Deserializer实现类接口的默认实现类,功能就是将InputStream转换为Java Object。在转换前需要先指定classLoader,用来检查要转换的java Object的类的信息。

核心代码为

ObjectInputStream objectInputStream = new ConfigurableObjectInputStream(inputStream, this.classLoader);
try {
  return objectInputStream.readObject();
}
catch (ClassNotFoundException ex) {
  throw new NestedIOException("Failed to deserialize object type", ex);
}

DeserializingConverter

该类主要用来将字节数组准换为java对象,核心代码如下

public Object convert(byte[] source) {
  ByteArrayInputStream byteStream = new ByteArrayInputStream(source);
  try {
    return this.deserializer.deserialize(byteStream);
  }
  catch (Throwable ex) {
    throw new SerializationFailedException("Failed to deserialize payload. " +
        "Is the byte array a result of corresponding serialization for " +
        this.deserializer.getClass().getSimpleName() + "?", ex);
  }
}

SerializationDelegate

SerializationDelegate是序列化和反序列化比较重要和常用的类,该类实现了SerializerDeserializer,可以同时支持序列化和反序列化

core.log 包是对Log的桥接,不再赘述

core包下的类

  1. AliasRegistry: 别名注册器接口。可以注册别名,删除别名,获取所有别名和判断名称是否为别名。(个人认为放在spring-core中不合适,可以放在spring-beans中。因为spring-core中基本都是工具类,基本没有和Spring的概念相关)

  2. AttributeAccessor: 对象属性的访问接口,可以设置属性,访问属性,删除属性和判断属性是否存在。(个人同样认为将该接口移入spring-beans中更合适)

  3. AttributeAccessorSupport: 为AttributeAccessor的实现类,内部存储结构是个LinkedHashMap,所有属性的操作都是对Map的操作。Map的Key为String,Value为Object。
  4. BridgeMethodResolver: 桥接方法的解析器。获取桥接方法的原始方法。判断桥接方法实际上是通过判断方法名、参数的个数以及泛型类型参数来获取的。

BridgeMethodResolver判断桥接的核心方法

MethodFilter filter = candidateMethod ->
					isBridgedCandidateFor(candidateMethod, bridgeMethod);
ReflectionUtils.doWithMethods(bridgeMethod.getDeclaringClass(), candidateMethods::add, filter);
if (!candidateMethods.isEmpty()) {
  bridgedMethod = candidateMethods.size() == 1 ?
      candidateMethods.get(0) :
      searchCandidates(candidateMethods, bridgeMethod);
}

private static boolean isBridgedCandidateFor(Method candidateMethod, Method bridgeMethod) {
  return (!candidateMethod.isBridge() && !candidateMethod.equals(bridgeMethod) &&
      candidateMethod.getName().equals(bridgeMethod.getName()) &&
      candidateMethod.getParameterCount() == bridgeMethod.getParameterCount());
}

ReflectionUtils的工具方法

public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) {
		// Keep backing up the inheritance hierarchy.
		Method[] methods = getDeclaredMethods(clazz, false);
		for (Method method : methods) {
			if (mf != null && !mf.matches(method)) {
				continue;
			}
			try {
				mc.doWith(method);
			}
			catch (IllegalAccessException ex) {
				throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
			}
		}
		if (clazz.getSuperclass() != null && (mf != USER_DECLARED_METHODS || clazz.getSuperclass() != Object.class)) {
			doWithMethods(clazz.getSuperclass(), mc, mf);
		}
		else if (clazz.isInterface()) {
			for (Class<?> superIfc : clazz.getInterfaces()) {
				doWithMethods(superIfc, mc, mf);
			}
		}
	}

同构以上两个方法找出所有的符合桥接候选方法的方法集合。查找桥接方法的原方法,会先从当前类中查找,然后再从父类中,如果父类中还没有的话,会再从所有的实现接口里去找。

简单理解就是:子类继承的泛型方法,如果方法参数为子类指定泛型的具体类型,则为非桥接方法。如果为非具体类型,则为桥接方法

后续的源码再开文章分析

参考文档

java中的桥接方法


版权声明:本文由 followtry 在 2021年05月07日发表。本文采用CC BY-NC-SA 4.0许可协议,非商业转载请注明出处,不得用于商业目的。
文章题目及链接:《Spring学习--SpringCore包的结构和主要功能》




  相关文章:

「游客及非Github用户留言」:

「Github登录用户留言」:

TOP