比如现在有一个简单的 Employee 的 POJO 类,因为要数据库操作所以要用 Spring 的 JPA 就得在类里加上 Entity 的注释,但是这样就有 Spring 的 context 了。
现在因为很多其他的微服务都需要这个类,想把这个类拿到不带 Spring 的共用的 package 下面就做不到,不得不维护两个类,一个是带 Spring 的一个是不带给其他微服务用比如 unwrap json 之类的,有没有什么比较好的办法只用维护一个?
1
kingfalse 2020-11-29 02:10:05 +08:00 via Android
运行时动态字节码复制一个?这个倒是也好做
|
2
pelloz 2020-11-29 02:24:49 +08:00
你这个类是单独一个共享依赖吧,你在 pom 里面将 JPA 相关依赖设置为 <scope>provided</scope> 就好了。
不过我觉得你的意思估计是写了一个类,然后到处复制粘贴....那就没有好办法了 |
3
nvkou 2020-11-29 02:32:54 +08:00 via Android
微服务不是业务独立吗?其他程序至少用不到这个类。
跨系统间传输可以再转一个通用 pure pojo 然后分包做依赖 |
4
cheng6563 2020-11-29 03:04:57 +08:00 via Android
写个父类或接口打上 @Entity 注解,其他项目也自己写一个不带注解的父类或接口,要处理好项目依赖问题
|
5
RedrumSherlock OP @nvkou 是业务独立,但是某些微服务之间还是有一些共用的 model,我们这些一般都丢一个类似 lib 或者 util 的包里,然后每个微服务 import 进来减少冗余。
分包做依赖具体是怎么操作?就还是一个 pojo 用来跨系统,然后分包再建一个带注解的做 JPA 操作? |
6
340244120w 2020-11-29 06:10:38 +08:00 via iPhone
最原始的 Xml 就是做这个的呀
|
7
RedrumSherlock OP @340244120w 是啊,现在一个想法就是不用注解回归 xml,但是 Spring boot 好像 2.0 以后要回 xml 不太方便,不再去自动找默认的那些 xml 文件了,得自己写几个 configuration
|
9
mind3x 2020-11-29 06:47:43 +08:00 4
你这需要共用的不是 model,而是 DTO 。Entity 和 DTO 之间分层并且互相转换是常见的基本操作。
|
10
tension2012 2020-11-29 07:14:10 +08:00
如果一个普通的 POJO 类,要做 O-R Mapping 的话, 无论是 annotation 还是 xml 方式,你至少要告诉程序, 你是怎么个映射规律, 比如你的 table name 是什么, 你的 column name 是什么, 你的 primary key 等等?
不过,如果什么都不做的话, 那就只能程序到 mysql 的那些系统字典表里去查对应的表名,列名和类型, 然后自己去组装一个类, 但是这样对命名规范很严格, 很容易出现映射错误的问题 |
11
VeryZero 2020-11-29 10:35:55 +08:00
|
12
Braisdom 2020-11-29 10:40:49 +08:00
我一直都不明白,为什么会存在 POJO,VO,DTO, Entity 这些概念,纯属过于理论化的抽象,脱离实践太远,完全没有考虑开发过程中的理解的复杂度。
|
13
hantsy 2020-11-29 11:00:13 +08:00
微服务一个最基本的原则,每个服务要实现自治(开发,测试,发部周期不影响其它的服务),服务之间使用轻量协议交互(比如, HTTP,Message Broker 等)。
对于你的情况,说白了你的程序根本就不是微服务架构,微服务压根就不会用到数据库相关代码共享。如果要共享,也只有协议数据格式( Http 的内容数据格式,Message Payload 规格)可以共享。 没有准备好 MS,就不要强行往上面靠,微服务架构跟你的所有的框架没太多关系,你的程序并不是用了 Spring Cloud 或者其它什么微服务框架就是微服务架构,很多人只是使用某种框架“碰瓷”微服务而已。 |
14
mejee 2020-11-29 11:03:33 +08:00 via iPhone
9 楼正解
|
15
xuanbg 2020-11-29 11:29:30 +08:00
别的服务用到就要自己搞个 DTO 用于反序列化。要么你把这个 DTO 放到一个公共的包里面,别的服务引用这个包。但维护更新包版本又是一个麻烦事,所以这种方法不建议。还有个办法是别的服务直接用 Object 类型,如果只是甩给前端看看没有业务逻辑相关的话。
|
16
perfee 2020-11-29 17:35:33 +08:00
系统 A,系统 B 。
系统 B 要依赖系统 A,那么 A 就要有一个干净的对外的接口。否则 A 和 B 就太耦合了。 如果 A 和 B 都不想给对方开接口,那好了,搞一个中立的 C,C 来担任这个角色,发布干净的 API 或者 SPI,A B 共用。 所以,如果 POJO 类是共用的,它就不应该被 A 视作私有的,既然不是私有的,就不能夹杂私货。 如果 A 觉得维持这个干净的 api 太累了,应该搞一个独立的 C 来维护。 整体的意思还是要回到经常谈论的点上:内聚和耦合,你怎么处理这个关系。 |
17
Braisdom 2020-11-29 20:24:13 +08:00 1
刚刚仔细看了楼主的贴子,像这类问题也比较容易解决:动态代理
不同微服务中使用同一个领域模型是正常的,但不同微服务中根据自身的技术特性,对模型也会有不同的技术型定义,这是很正常的需求。 解决方法:在能用的 JAR 中通过 Java Interface 定义领域模型,JPA 中只是实现这个 Interface,其它的微服务只看到 Java Interface,在不同微服务之间进行模型传递时,通过一个动态代理的对象工厂创建这个接口的实例。 这样就可以不需要在所有的微服务中看到 JPA 的 Entity 了,它们看到的只有领域模型的 Interface,只不过需要定义好对象传输的协议,和反序列化的逻辑。 |
18
chenshun00 2020-11-30 09:44:46 +08:00
BeanUtils.Copy(source,target)
|
19
Aresxue 2020-11-30 15:40:08 +08:00
问题的原因就是你把 DO 和 DTO 变成一个了,这种做法本身是有点问题,但非要这么做也没事,client 包依赖 JPA 然后 JPA 的依赖变成 provided,实际 run 的应用中也有要 JPA 的依赖,两个依赖版本要尽量保持一致
|
20
Joker123456789 2020-11-30 16:11:37 +08:00
正确的做法就是维护两个类,所以不用改。
|
21
Jrue0011 2020-12-01 17:02:34 +08:00
或许可以寻找一个具有代码生成功能(注解处理器)的 mapper 框架,维护一个类,另一个提供给其他服务使用的类自动生成代码?
|