Spring Boot与Play、Struts等Java框架集成方案咨询
Spring Boot 与 Struts/Play 框架集成指南
一、Spring Boot + Struts 2 集成(相对成熟)
Struts 2 官方提供了 Spring 集成插件,核心是解决依赖冲突、路由协调和依赖注入兼容问题。
1. 依赖管理(解决冲突)
Struts 2 自带的 Servlet API、日志组件与 Spring Boot 存在冲突,需通过依赖排除处理。以下是 Maven 配置示例:
<dependencies> <!-- Spring Boot Web 核心 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Struts 2 核心 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>6.3.0.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Struts 2 Spring 集成插件 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>6.3.0.2</version> </dependency> </dependencies>
2. 路由与请求处理
通过注册 Struts 的核心过滤器,让其接管指定路径的请求,同时调整执行顺序确保优先于 Spring Boot 的 DispatcherServlet:
@Configuration public class StrutsConfig { @Bean public FilterRegistrationBean<StrutsPrepareAndExecuteFilter> strutsFilter() { FilterRegistrationBean<StrutsPrepareAndExecuteFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new StrutsPrepareAndExecuteFilter()); registration.addUrlPatterns("/*"); // 可指定前缀如 /struts/** 实现路由分流 registration.setOrder(1); // 确保先于Spring的DispatcherServlet执行 return registration; } }
Struts 自身路由仍通过 struts.xml 配置,示例:
<struts> <!-- 指定Spring为对象工厂,实现DI兼容 --> <constant name="struts.objectFactory" value="spring"/> <package name="default" namespace="/" extends="struts-default"> <action name="hello" class="com.example.HelloAction"> <result name="success">/hello.jsp</result> </action> </package> </struts>
3. 依赖注入实现
由于指定了 Spring 作为 Struts 的对象工厂,Struts Action 可直接使用 @Autowired 注入 Spring 管理的 Bean:
public class HelloAction extends ActionSupport { @Autowired private SomeSpringService springService; @Override public String execute() { String message = springService.getGreeting(); ActionContext.getContext().put("greeting", message); return SUCCESS; } }
二、Spring Boot + Play Framework 集成(建议轻量化)
Play 是全栈式框架,自带 Netty 容器、Guice DI 和独立路由体系,与 Spring Boot 深度集成冲突较多,优先推荐微服务拆分,若需同 JVM 集成可参考以下方案:
1. 依赖隔离(核心难点)
需排除 Spring Boot 与 Play 冲突的核心依赖,比如替换 Tomcat 为 Netty:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 改用Netty适配Play的容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-netty</artifactId> </dependency> <!-- Play核心依赖(需注意版本兼容性) --> <dependency> <groupId>com.typesafe.play</groupId> <artifactId>play_2.13</artifactId> <version>2.8.19</version> </dependency>
2. 路由分流
通过 Spring Boot 的 HandlerMapping 将指定路径转发给 Play 的 HttpHandler:
@Configuration public class PlayIntegrationConfig { @Bean public SimpleUrlHandlerMapping playHandlerMapping() { SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); // 将/play前缀的请求交给Play处理 mapping.setUrlMap(Map.of("/play/**", playHttpHandler())); mapping.setOrder(0); // 优先处理Play路由 return mapping; } @Bean public HttpHandler playHttpHandler() { // 初始化Play应用(需根据实际项目调整路径和模式) Application playApp = new DefaultApplication( new File("."), Thread.currentThread().getContextClassLoader(), null, Mode.PROD ); return playApp.getHttpHandler(); } }
Play 自身路由仍通过 conf/routes 文件配置,仅处理 /play 前缀下的请求。
3. 依赖注入互通
可通过手动桥接 Spring 上下文与 Play 的 Guice 容器,实现 Bean 互相调用:
- 在 Spring 中注册 Guice 管理的 Bean:
@Bean public SomePlayService somePlayService() { Injector injector = Guice.createInjector(new PlayModule()); return injector.getInstance(SomePlayService.class); }
- 在 Play 中获取 Spring 上下文:
public class PlayController extends Controller { public Result callSpringService() { ApplicationContext springContext = SpringApplication.run(Application.class).getApplicationContext(); SomeSpringService springService = springContext.getBean(SomeSpringService.class); return ok(springService.getResult()); } }
三、通用最佳实践
- 优先微服务拆分:避免框架深度集成,将 Spring Boot、Struts/Play 作为独立服务,通过 REST API 通信,彻底解决依赖冲突和耦合问题。
- 依赖冲突排查:用
mvn dependency:tree(Maven)或./gradlew dependencies(Gradle)分析依赖树,排除重复或版本不一致的组件(如 Servlet API、日志框架、JSON 库)。 - 使用官方集成插件:Struts 2 的
struts2-spring-plugin是官方维护的集成方案,避免自行编写兼容代码。 - 测试隔离验证:集成后分别测试各框架的核心功能(路由跳转、DI 注入、请求处理),确保互不干扰。
内容的提问来源于stack exchange,提问作者Ben Billion
相关产品推荐
相关产品推荐

