AbstractHttpMessageConverter中read与readInternal的区别及双方法设计原因咨询
为什么AbstractHttpMessageConverter同时有read和readInternal两个方法?
这个问题问得特别到位!我刚接触Spring Web的消息转换器时,也对这俩方法的分工摸不着头脑,咱们从设计思路和实际价值来唠清楚:
1. 模板方法模式的经典实践
你看源码里read()是被final修饰的,这就意味着子类不能重写它——它负责固定的通用流程框架,哪怕现在的实现只是简单委托给readInternal(),但注释也说了“未来的实现可能会添加一些默认行为”。
而readInternal()是抽象方法,必须由子类实现,它只专注于具体的对象反序列化逻辑:比如把HTTP输入流里的JSON/XML数据转换成对应的Java对象。
这种设计的好处是:框架牢牢把控住通用流程的入口和可能的扩展点,子类只需要聚焦自己的业务解析逻辑,不用重复编写日志、异常处理、前置校验这类通用代码。
2. 清晰的职责分离
read():对外暴露的统一调用入口,定义了读取操作的标准协议。调用方(比如Spring MVC的请求处理流程)只需要调用这个方法,完全不用关心内部怎么解析。readInternal():隐藏在内部的核心实现细节,只负责把HTTP输入消息转换成目标对象,这部分是每个消息转换器独有的逻辑,交给子类定制最合理。
3. 为未来扩展留足空间
现在的read()看起来只是个“转发器”,但它的存在是为了兼容未来的需求变化。比如以后Spring想在读取前加个全局的请求头校验、读取后加个对象的统一初始化/校验,或者加个性能监控日志,直接在read()里加逻辑就行,所有子类的代码都不用改,完美兼容旧实现。
举个实际例子:像MappingJackson2HttpMessageConverter(Spring里处理JSON的转换器),它只需要实现readInternal(),专注于把输入流的JSON转成Java对象;而通用的流程管控,全交给父类的read()来处理。
内容的提问来源于stack exchange,提问作者sibo.wang
相关产品推荐
相关产品推荐

