如何在多个Spring Boot微服务应用间共享带JPA定义的Employee实体并打包为独立Jar
如何抽取带JPA注解的Employee实体为独立共享Jar包
这个需求在微服务架构里太常见了,我给你一步步拆解实现方案,保证AppA和AppB都能顺畅使用这个共享实体:
1. 新建独立的实体模块(非Spring Boot应用)
首先别直接在Spring Boot项目里拆,要建一个纯Java库模块——因为Spring Boot的starter会带很多不必要的依赖,共享实体只需要JPA的API注解就够了。
Maven示例配置(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yourcompany</groupId> <artifactId>employee-shared-model</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <dependencies> <!-- 只引入JPA API,够实体注解用就行,scope设为provided避免重复打包 --> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- 要是用Lombok简化代码,也加上,设为optional不强制依赖 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <optional>true</optional> </dependency> </dependencies> </project>
迁移Employee实体类
把你原来AppA里的Employee类移到这个新模块的对应包下,保持原有注解不变:
package com.yourcompany.shared.model; import jakarta.persistence.Entity; import jakarta.persistence.Table; @Entity @Table(name = "employees") public class Employee { // 你的字段、构造方法、getter/setter都原样保留 }
2. 在AppA和AppB中引入共享依赖
先把这个共享模块执行mvn install(Gradle的话是gradle publishToMavenLocal),推到本地仓库,然后在两个Spring Boot应用的依赖配置里加上:
Maven(AppA和AppB的pom.xml)
<dependency> <groupId>com.yourcompany</groupId> <artifactId>employee-shared-model</artifactId> <version>1.0.0</version> </dependency>
Gradle(build.gradle)
implementation 'com.yourcompany:employee-shared-model:1.0.0'
3. 让AppA的JPA扫描到共享实体
因为Employee现在不在AppA的本地包下了,得告诉JPA去哪里找它。在AppA的主启动类上加上@EntityScan注解,指定共享实体的包路径:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; @SpringBootApplication @EntityScan(basePackages = {"com.yourcompany.appa", "com.yourcompany.shared.model"}) public class AppAApplication { public static void main(String[] args) { SpringApplication.run(AppAApplication.class, args); } }
如果你的共享包和AppA的主包有父级关系(比如都是com.yourcompany下的),直接扫父包更省事:@EntityScan(basePackages = "com.yourcompany")
4. AppB直接使用共享实体
你原来AppB里的代码完全不用改!因为现在Employee类来自共享Jar,作为REST响应的DTO直接用就行:
ResponseEntity<Employee[]> response = restTemplate.getForEntity("http://localhost:8080/employees/", Employee[].class); Employee[] employees = response.getBody();
这里要注意:AppB不需要引入JPA相关依赖(除非它自己也要操作数据库),因为共享模块的JPA API是provided scope,不会给AppB带来额外负担,纯纯用它当DTO。
几个额外提醒
- 版本统一:AppA和AppB一定要用同一个版本的共享Jar,不然容易出现序列化/反序列化问题。
- 序列化兼容:确保
Employee类的字段都有对应的getter/setter,或者用Jackson的@JsonProperty注解,避免AppB接收响应时反序列化失败。 - 依赖冲突:如果共享模块加了其他依赖,最好和Spring Boot的依赖管理对齐,用它来统一版本,避免 jar hell。
内容的提问来源于stack exchange,提问作者Rpj
相关产品推荐
相关产品推荐

