ow+ vs Spring MVC:两份对日 Java 经验的全景对比

技术 · 约 25 分钟

本文是 NRI 闭源 Java 商业框架全景 与 Spring MVC 核心机制深度解析 的姐妹篇。前两篇分别讲了”是什么”,这一篇讲**“区别在哪、为什么有这些区别、对你有什么用”**。

为什么这个对比值得专门写一篇

如果你正在对日 Java 圈子、或者准备从对日项目跳出去,这两组框架大概率你都会遇到:

  • NRI ow+ / o3w:你当前在做的事;200+ 人的大型项目主流;规则严、迁移性弱;
  • Spring MVC:全球 Java Web 事实标准;招聘必问;灵活、迁移性强;
  • OW X(NRI 转型版):正在发生的过渡——底层切到 Spring,但规约还是 NRI 那套。

搞清楚两者的差异,等于搞清楚三件事:你的经验里哪些值钱、哪些会归零、哪些要被”翻译”成简历语言。

一页总览

维度NRI ow+Spring MVC
出身野村综研自研,闭源商业框架Rod Johnson 开源(现 VMware / Broadcom)
时代2009 正式发布;2000 前内部已用2003 第一版;当前 6.x
设计目标标准化、规则强制、防人为错误灵活、可插拔、生态丰富
调度入口ActionServlet(Front Controller,XML 配置)DispatcherServlet(唯一 Servlet,注解配置)
控制器Action 类(STUDIO 生成壳,PG 填业务)@Controller 方法(开发者全程写)
业务层Service + Logic 两层(壳 + 手写)@Service 单层(DI 注入)
数据层SQL 外部化(ow+ 专属配置)MyBatis / JPA / JdbcTemplate
DTO 风格每层专属 DTO,类型不同一个 DTO 贯穿
配置方式Excel 定义表 → STUDIO 生成注解 + application.yml
视图层JSP + Taglib(2009 主流)JSON / REST(2025 主流)
异常处理SystemException / BusinessException + MessageID@RestControllerAdvice + @ExceptionHandler
拦截器ow+ 自定义拦截器接口HandlerInterceptor / Servlet Filter
生态几乎无(闭源)庞大(Spring 全家桶)
上手成本2 周做模块1 天起步
可迁移性弱(离开 NRI 项目归零)强(任何 Java 项目通用)

下面从五个角度分别展开。


一、请求链路对比:流水线 vs 插拔

最直观的差异——同一个 GET /user/42,两个框架怎么走完。

请求链路对比 · ow+ vs Spring MVC

ow+ 的设计哲学:让”每个环节该做什么”用 XML 配置 + 生成代码锁死,开发者只能按框架规定的方式填空。

Spring MVC 的设计哲学:只规定”入口和边界”,把”中间怎么做”以接口形式留给开发者扩展。

实际差异:

环节ow+Spring MVC
入口配置web.xml 里配 ActionServlet + URL pattern@SpringBootApplication 注解 + 自动注册
URL → Handlerstruts-config.xml / 框架自带配置@RequestMapping("/user/{id}")
参数转换BeanUtils.copyProperties 框架自动HttpMessageConverter + 自定义 Converter
业务入口Action 类继承自框架基类普通 POJO + @Controller 注解
业务层Service(壳)+ Logic(手写)@Service 一层搞定
视图返回字符串逻辑视图名 → ViewResolver@ResponseBody 直接写 JSON,跳过视图
拦截器XxxInterceptor 继承自框架接口HandlerInterceptor 实现 pre/post/after

关键观察:ow+ 的链路是封闭式流水——每一站都有”必须这样做”的规定;Spring MVC 的链路是开放式接力——每一站都有”可以这样做”的口子。两种风格没有绝对优劣,前者适合 200 人外包团队,后者适合 3-10 人的敏捷团队。


二、核心组件对比:可见的工具 vs 隐形的接口

核心组件对比 · 角色分工

ow+ 的核心调度其实是 STUDIO——你看不到它,但它生成的代码决定了所有组件怎么工作。

Spring MVC 的核心调度是 DispatcherServlet——所有”我该找谁干活”的问题都由它处理,并且所有参与者都是接口,可以替换。

具体差异:

组件ow+Spring MVC
调度中心STUDIO(离线工具)+ ActionServlet(运行时)DispatcherServlet
URL 路由XML 配置文件(编译期固化)HandlerMapping 接口(运行时计算)
Handler 适配不需要适配器(Action 都继承同一基类)HandlerAdapter 接口(多种 Handler 形态可共存)
视图解析struts-config.xml 配前缀后缀ViewResolver 接口链(Thymeleaf/Freemarker/PDF…)
数据转换Action 框架基类自动处理HttpMessageConverter(Jackson / JAXB / Form)
拦截器框架自定义接口HandlerInterceptor 标准三方法

Spring MVC 设计上更”面向接口”——这是它能演进出 WebFlux、GraphQL、gRPC 等各种变体的根本原因;ow+ 想扩展一个新东西(比如改用 Thymeleaf),得动框架本身,难度完全不在一个量级。


三、DTO 流转对比:一对多 vs 一对一

这是我见过最容易引发争论的差异——

DTO 流转对比 · 一对多 vs 一对一

ow+ 强制每层用不同类型的 DTO:画面 DTO、Action DTO、Service DTO、Logic DTO、DAO DTO,五个。

Spring MVC 几乎不限制:一个 UserDTO 从 Controller 走到 Service 再到 Repository,全程复用。

为什么要这么设计?两套逻辑完全不同:

ow+ 的逻辑:用”类型不同”做编译期防火墙——Service 层只能拿到 Service DTO,画面字段根本传不到业务层,靠编译器防止越层。

Spring MVC 的逻辑:用”职责划分”做软约束——DTO 只是一个数据载体,靠团队规约和 code review 防止越层。

实际代价:

代价ow+Spring MVC
模板代码大量(5 个 DTO + 字段映射)几乎无
IDE 友好度字段改名要改 5 处改一处
学习曲线陡(要搞清 5 个 DTO 的关系)平(一个类走到底)
安全性强(编译器兜底)弱(靠人)
性能差(多了几次属性拷贝)好
适合规模200+ 人外包3-50 人敏捷

OW X 的折中:沿用 Spring 风格(一个 DTO 走到底),但引入自家规约做补救——比如规定 Service 层的返回值必须是另一个 XxxOutDTO,用 code review + 静态检查工具兜底。这是 2020 年后 NRI 项目的实际做法。


四、开发范式对比:流水线 vs 单兵

开发范式对比 · 流水线 vs 单兵

ow+ 的开发是流水线:

SE 写 Excel 定义表 → STUDIO 生成代码 → PG 在生成代码里填空 → 单体测试

Spring MVC 的开发是单兵:

开发者写 Controller 方法 → 启动 Spring Boot → MockMvc 单测 → Postman 联调

这是角色分工的根本差异:

角色ow+ 项目Spring MVC 项目
系统设计SE(专门的人)开发者自己
代码生成STUDIO(工具)不需要
业务实现PG(专门的人)开发者自己
测试PG 单测开发者 + QA

ow+ 这种角色分工适合大型外包项目——SE 把设计做完、PG 把代码填好,分工明确、上手快、产出稳定;但代价是个人成长受限:PG 写三年可能都不会设计一个完整的业务模块。

Spring MVC 这种”单兵”模式适合产品团队——每个人都从设计做到上线,能力成长快;但代价是对个人能力要求高:你得懂架构、懂业务、懂测试。


五、八大维度详细对比

1. 控制器与路由

// ow+ Action(继承框架基类)
public class UserSearchAction extends BaseAction {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest req, HttpServletResponse res) {
        UserSearchForm f = (UserSearchForm) form;
        List<UserDTO> users = userService.search(f.getKeyword());
        req.setAttribute("users", users);
        return mapping.findForward("success");
    }
}

// Spring MVC Controller(普通 POJO)
@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/search")
    public List<UserDTO> search(@RequestParam String keyword) {
        return userService.search(keyword);
    }
}

ow+ 的 Action 必须继承基类(受约束),方法签名固定(不能选参数);Spring MVC 的 Controller 任何类都行,方法签名随便写。

2. 数据绑定

// ow+:画面提交自动绑定到 FormBean(由 Excel 定义)
// FormBean 字段上由 STUDIO 根据 Excel 注解加上校验
public class UserSearchForm extends ActionForm {
    private String keyword;  // STUDIO 已加 @NotBlank
    // getter / setter
}

// Spring MVC:@RequestParam / @PathVariable / @RequestBody 显式声明
@GetMapping("/search")
public List<UserDTO> search(@RequestParam(required = false) String keyword) { ... }

@PostMapping("/save")
public Result save(@Valid @RequestBody UserSaveDTO dto) { ... }

Spring MVC 把”绑定什么”完全交给开发者写注释,更灵活但也更容易漏。

3. 事务管理

<!-- ow+:在 XML 配置 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
  </tx:attributes>
</tx:advice>
// Spring:注解声明
@Transactional(rollbackFor = Exception.class)
public void saveOrder(OrderDTO order) { ... }

ow+ 的 XML 事务更”集中”,适合全局策略统一;Spring 的 @Transactional 更”就近”,但容易出现自调用失效、AOP 不生效等陷阱。

4. 异常处理

// ow+:throw BusinessException 携带 MessageCode
throw new BusinessException("E00101", "余额不足");
// 框架自动翻译成用户可见的错误页
// Spring:@RestControllerAdvice + @ExceptionHandler
@RestControllerAdvice
public class GlobalHandler {
    @ExceptionHandler(InsufficientBalanceException.class)
    public Result<Void> handle(InsufficientBalanceException e) {
        return Result.fail("E00101", "余额不足");
    }
}

两者本质一样,Spring 的方式更显式、更易测试;ow+ 的方式更”约定俗成”——但新人不知道有哪些 MessageCode,需要查文档。

5. SQL 与数据层

// ow+:SQL 写在特定 XML 里
// UserDao.xml.xml
<select id="searchByKeyword" resultClass="UserDTO">
  SELECT * FROM T_USER WHERE NAME LIKE '%' || ? || '%'
</select>
// Spring + MyBatis(ow+ 的很多设计参考自 MyBatis)
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM t_user WHERE name LIKE CONCAT('%', #{kw}, '%')")
    List<UserDTO> searchByKeyword(@Param("kw") String keyword);
}

ow+ 的 SQL 写在专属 XML 文件,与 MyBatis 思想同源——这个事实很多人不知道。学 ow+ 的 SQL 经验直接等于学 MyBatis。

6. 视图层

时代ow+Spring MVC
2009JSP + Struts Taglib(主流)JSP + Spring Taglib
2015仍是 JSP 为主开始大量用 Thymeleaf
2020JSP + 部分 Thymeleaf 改造JSON / REST 主导
2025OW X 项目:前后端分离为主几乎纯 REST

ow+ 的视图层是”时代遗物”——2009 主流的 JSP + Taglib 在 2025 年已经边缘化。OW X 项目的视图层实际上已经是前后端分离的 React/Vue + REST。

7. 拦截器与过滤器

// ow+:继承框架的拦截器接口
public class AuthInterceptor extends AbstractInterceptor {
    protected String doIntercept(ActionInvocation inv) throws Exception {
        // 检查登录
        if (notLoggedIn(inv)) {
            return "login";  // 返回逻辑视图名
        }
        return inv.invoke();
    }
}

// Spring:实现 HandlerInterceptor
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        // 检查登录
        if (notLoggedIn(req)) {
            res.sendRedirect("/login");
            return false;
        }
        return true;
    }
}

结构相似,Spring 多了 preHandle 返回 false 的短路能力,更灵活。

8. 测试

维度ow+Spring MVC
单测入口extends BaseActionTest,手动 mock Service@WebMvcTest + @MockBean
不启容器是(ow+ 单元测试不依赖 AP Server)@WebMvcTest 启用 MockMvc 不启 Tomcat
集成测试起 ow+ 测试容器@SpringBootTest(webEnvironment = RANDOM_PORT)
覆盖率工具自家规约工具JaCoCo / SonarQube

ow+ 单元测试不依赖 AP Server 是 2009 年时一大卖点(参日経 xtech 2009 报道);Spring MVC 的 @WebMvcTest 在 2014 年后也达到了同等效果。


六、可迁移性矩阵:你换工作时哪些经验能用

能力可迁移性矩阵 · 谁的经验能带走

这是全文最实用的一张图——你下次面试的时候,按这张图定位自己的”卖点”。

绿区(跨行业通用):任何 Java 岗都用得上,简历上直接强调:

  • 分层架构思想、单一职责
  • 复杂 SQL 调优(手写 SQL 的硬功夫)
  • REST / 前后端分离设计
  • 测试金字塔意识
  • 拦截器 / 过滤器 / AOP 的取舍

橙区(行业可迁移):保险 / 金融 / 对日开发圈能用:

  • ow+ 的分层与异常码体系(翻译成”统一异常处理”)
  • 大规模团队协作经验
  • 对日开发规范(設計書レビュー・単体テスト・障害対応)
  • DTO 契约设计

红区(NRI 项目专属):换工作立即归零——简历上少写或换种说法:

  • STUDIO 工具操作
  • o3w / ow+ 版本号
  • Action/Service/Logic 类名

一句话翻译术:把”我在 ow+ 项目里填了 3 年 Action 代码”翻译成”我做过 3 年大型金融系统的 Web 后端开发,深入理解分层架构、复杂 SQL 调优和统一异常处理”——招聘官立刻听懂。


七、OW X 是怎么取两者之长的

OW X 是 NRI 在 2018 年推出的过渡框架——它本质上就是 Spring Boot 加一层 NRI 规约。我在两篇文章里都提过,这里把”它具体怎么融合两者”展开:

维度OW X 的做法
底层Spring Boot 3.x + Spring Security + Spring Cloud(部分项目)
控制器@Controller / @RestController(Spring 风格)
业务层@Service(Spring 风格)+ NRI 的”Logic 切分”习惯保留
DTO一个 DTO 贯穿(Spring 风格)+ NRI 规约要求”服务层 DTO 与 Repository 层分开”
异常@RestControllerAdvice(Spring)+ MessageID 体系(NRI 保留)
视图前后端分离为主,老模块保留 JSP
拦截器HandlerInterceptor(Spring)+ NRI 规约的”必须有的拦截器清单”
部署Docker / Kubernetes(Spring Boot 友好)
安全Spring Security + NRI 自家 ID/角色体系
长期支持NRI 承诺 10 年 LTS(涵盖 Spring 与相关 OSS)

OW X 项目对你的意义:

  • 你学 ow+ 的分层思想、SQL 经验、复杂业务设计——这些都迁移到 OW X 继续有用;
  • 你学 ow+ 的 STUDIO 操作、Action 继承——这些归零;
  • 你需要主动补 Spring 经验——OW X 项目里”会用 Spring 全家桶”的人正在变成抢手资源。

八、给求职面试的回答模板

把这两组框架讲清楚,等于把自己的对日经验翻译成市场语言。面试时这么这样讲:

8.1 当面试官问”你用过什么框架”

"我过去 4 年在 NRI 体系的 ow+ 项目里做 Java 后端开发,这个项目是日方的闭源框架,
底层基于 Java EE。它的分层和异常处理设计得很严谨——每个业务模块都有
Action、Service、Logic 三层,每层用不同的 DTO 类型做隔离。

最近一年项目在做 OW X 迁移,底层切到 Spring Boot,
我也在补 Spring 全家桶的经验。
我认为 ow+ 的强约束和 Spring 的灵活性我都熟悉,能适应不同的团队风格。"

8.2 当面试官问”ow+ 和 Spring 区别”

直接对照本文第三、四、五节挑你最熟的两个维度讲:

"我理解下来最大的差异在两点:
一是 DTO 设计——ow+ 强制每层一个 DTO,类型不同、靠编译器防越层;
   Spring 一个 DTO 走到底,靠团队规约和 code review 防越层。
二是开发流程——ow+ 是 SE 填 Excel 定义表、STUDIO 生成代码、
   PG 在生成代码里填业务;Spring 是开发者一个人写完 Controller 到 Service。
   前者适合大规模外包、产出稳定,后者适合敏捷团队、成长快。"

8.3 当面试官追问”你从 ow+ 学到了什么”

"在 ow+ 项目里我学到最多的是三件事:
一是分层和边界——每层 DTO 不同确实繁琐,但防止了业务逻辑溢到画面层;
二是 SQL 调优——ow+ 用 SQL 外部化、不走全自动 ORM,
   复杂报表 SQL 必须自己写,这块硬功夫我比较扎实;
三是大型团队协作——200+ 人项目怎么保证代码风格一致,
   怎么靠工具而不是靠人来兜底规则。"

这三个全部落在绿区和橙区——是你简历上最值钱的卖点。


九、一页清单

请求链路:ow+ 流水线 / Spring MVC 插拔
组件分工:ow+ STUDIO 隐形调度 / Spring MVC 接口可见
DTO 流转:ow+ 每层专属 / Spring MVC 贯穿
开发范式:ow+ SE + PG / Spring MVC 单兵
异常处理:ow+ MessageID / Spring @RestControllerAdvice
SQL 风格:ow+ 专属 XML / Spring + MyBatis 同源思想
视图层:ow+ JSP 为主 / Spring REST 为主
拦截器:ow+ AbstractInterceptor / Spring HandlerInterceptor
测试:ow+ 不启 AP Server / Spring @WebMvcTest
迁移性:ow+ 弱(离开 NRI 归零)/ Spring 强(跨项目通用)
OW X:取两者之长,Spring 底座 + NRI 规约
简历翻译:把 ow+ 经验翻译成"分层 + SQL + 团队协作"

后续可以挖的方向

  • OW X 项目的具体规约(异常码体系、MDC 日志上下文、TraceId 传递)
  • Spring Boot 3.x 在 OW X 项目里的应用
  • 从 ow+ 转 Spring 的实战改造案例(已有项目如何平滑切换)
  • MyBatis 与 ow+ SQL 外部化的细节对比

把本文第八节的三个模板背下来,能覆盖对日 Java 转型面试 80% 的框架类问题。

阳熙

Java / 保险业务系统开发 · 无锡

← 返回文章列表

评论

还没有评论,来留第一条吧。

首次评论会做人机校验