如何开发可同时被Jakarta和Spring项目使用的通用公共类库?
完全可行,你设想的「技术无关核心层+生态适配包」的分层方案就是当前最成熟的实现思路,不存在更轻量化的通用方案——Spring和Jakarta EE的组件模型、依赖注入、配置体系原生不兼容,必须通过隔离层做适配才能实现跨生态复用。
1 核心层实现要求
核心层要完全脱离两大生态的API,只做纯业务逻辑的封装:
- 所有需要依赖容器能力的场景(比如配置读取、Bean获取、事务绑定、异步调用)全部定义成SPI接口,核心层仅面向接口编程,不绑定任何具体实现。
- 打包时不要引入任何Spring、Jakarta EE/JavaEE的依赖,哪怕是
providedscope也不要加,避免传递依赖污染接入项目的依赖树。 - 核心层的类不要加任何生态专属的注解(比如
@Inject、@Autowired、@ApplicationScoped、@Component等),所有依赖通过构造方法传入,由上层适配层负责实例组装。
2 生态适配层实现要求
分别为Spring、Jakarta EE开发单独的适配包,仅负责核心层SPI接口的生态-specific实现:
2.1 Jakarta EE适配包
- 实现核心层的全部SPI接口:配置读取用MicroProfile Config实现、Bean实例化用CDI Producer注入、EJB相关组件封装成CDI托管Bean。
- 可自定义CDI Stereotype注解,简化EE项目的接入成本,项目引入适配包后只要开启CDI扫描就能自动注册核心层组件。
- 可按需引入CDI、EJB、MicroProfile等EE专属依赖,scope设为
provided,由接入的EE项目运行环境提供实现。
2.2 Spring适配包
- 实现核心层的全部SPI接口:配置读取用Spring
Environment抽象实现、Bean实例化通过ApplicationContext获取、事务逻辑封装适配Spring事务管理器。 - 对于Spring Boot场景,可通过
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports注册自动配置类,实现引入依赖即自动加载核心组件的效果。 - 提供
@EnableXxx系列注解,兼容非Spring Boot的普通Spring项目手动开启组件注册。
3 轻量化优化方案(仅适合简单场景)
如果你的公共类库功能简单,仅用到依赖注入、配置读取两个基础能力,不需要用到EJB、事务等复杂容器特性,可以用以下方案缩减适配层代码量:
- 同一个配置类同时加两大生态的组件注解:
@org.springframework.context.annotation.Configuration+@jakarta.enterprise.context.ApplicationScoped,两大生态会自动识别自身支持的注解,忽略不识别的注解,无需做代码隔离。 - 配置层不依赖两大生态的原生配置能力,统一引入无外部依赖的轻量第三方配置库(比如OWNER),省去配置逻辑的适配代码。
4 注意事项
- 如果需要兼容JavaEE 8及之前的
javax.*命名空间的旧项目,需要单独开发基于javax包的EE适配包,和Jakarta EE 9+的jakarta.*适配包分开发布,避免包名冲突。 - 核心层和两个适配包使用统一的版本号发布,避免出现版本不匹配导致的运行时异常。
内容的提问来源于stack exchange,提问作者LostMekka
相关产品推荐
相关产品推荐

