Spring 相关,有没有什么好的解决方案

2020-11-29 02:08:32 +08:00
 RedrumSherlock

比如现在有一个简单的 Employee 的 POJO 类,因为要数据库操作所以要用 Spring 的 JPA 就得在类里加上 Entity 的注释,但是这样就有 Spring 的 context 了。

现在因为很多其他的微服务都需要这个类,想把这个类拿到不带 Spring 的共用的 package 下面就做不到,不得不维护两个类,一个是带 Spring 的一个是不带给其他微服务用比如 unwrap json 之类的,有没有什么比较好的办法只用维护一个?

3174 次点击
所在节点    Java
22 条回复
kingfalse
2020-11-29 02:10:05 +08:00
运行时动态字节码复制一个?这个倒是也好做
pelloz
2020-11-29 02:24:49 +08:00
你这个类是单独一个共享依赖吧,你在 pom 里面将 JPA 相关依赖设置为 <scope>provided</scope> 就好了。
不过我觉得你的意思估计是写了一个类,然后到处复制粘贴....那就没有好办法了
nvkou
2020-11-29 02:32:54 +08:00
微服务不是业务独立吗?其他程序至少用不到这个类。
跨系统间传输可以再转一个通用 pure pojo 然后分包做依赖
cheng6563
2020-11-29 03:04:57 +08:00
写个父类或接口打上 @Entity 注解,其他项目也自己写一个不带注解的父类或接口,要处理好项目依赖问题
RedrumSherlock
2020-11-29 05:05:18 +08:00
@nvkou 是业务独立,但是某些微服务之间还是有一些共用的 model,我们这些一般都丢一个类似 lib 或者 util 的包里,然后每个微服务 import 进来减少冗余。

分包做依赖具体是怎么操作?就还是一个 pojo 用来跨系统,然后分包再建一个带注解的做 JPA 操作?
340244120w
2020-11-29 06:10:38 +08:00
最原始的 Xml 就是做这个的呀
RedrumSherlock
2020-11-29 06:19:50 +08:00
@340244120w 是啊,现在一个想法就是不用注解回归 xml,但是 Spring boot 好像 2.0 以后要回 xml 不太方便,不再去自动找默认的那些 xml 文件了,得自己写几个 configuration
zhazi
2020-11-29 06:38:31 +08:00
使用 @entity 跟 spring 的 context 一点关系都没有。
mind3x
2020-11-29 06:47:43 +08:00
你这需要共用的不是 model,而是 DTO 。Entity 和 DTO 之间分层并且互相转换是常见的基本操作。
tension2012
2020-11-29 07:14:10 +08:00
如果一个普通的 POJO 类,要做 O-R Mapping 的话, 无论是 annotation 还是 xml 方式,你至少要告诉程序, 你是怎么个映射规律, 比如你的 table name 是什么, 你的 column name 是什么, 你的 primary key 等等?

不过,如果什么都不做的话, 那就只能程序到 mysql 的那些系统字典表里去查对应的表名,列名和类型, 然后自己去组装一个类, 但是这样对命名规范很严格, 很容易出现映射错误的问题
VeryZero
2020-11-29 10:35:55 +08:00
@mind3x 同意,如果多个微服务需要依赖同一个 model,说明服务拆分有问题。。

不过我们公司也是这么干的😄 区别就是我们用的 MyBatis,所以貌似没这问题
Braisdom
2020-11-29 10:40:49 +08:00
我一直都不明白,为什么会存在 POJO,VO,DTO, Entity 这些概念,纯属过于理论化的抽象,脱离实践太远,完全没有考虑开发过程中的理解的复杂度。
hantsy
2020-11-29 11:00:13 +08:00
微服务一个最基本的原则,每个服务要实现自治(开发,测试,发部周期不影响其它的服务),服务之间使用轻量协议交互(比如, HTTP,Message Broker 等)。

对于你的情况,说白了你的程序根本就不是微服务架构,微服务压根就不会用到数据库相关代码共享。如果要共享,也只有协议数据格式( Http 的内容数据格式,Message Payload 规格)可以共享。

没有准备好 MS,就不要强行往上面靠,微服务架构跟你的所有的框架没太多关系,你的程序并不是用了 Spring Cloud 或者其它什么微服务框架就是微服务架构,很多人只是使用某种框架“碰瓷”微服务而已。
mejee
2020-11-29 11:03:33 +08:00
9 楼正解
xuanbg
2020-11-29 11:29:30 +08:00
别的服务用到就要自己搞个 DTO 用于反序列化。要么你把这个 DTO 放到一个公共的包里面,别的服务引用这个包。但维护更新包版本又是一个麻烦事,所以这种方法不建议。还有个办法是别的服务直接用 Object 类型,如果只是甩给前端看看没有业务逻辑相关的话。
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 来维护。

整体的意思还是要回到经常谈论的点上:内聚和耦合,你怎么处理这个关系。
Braisdom
2020-11-29 20:24:13 +08:00
刚刚仔细看了楼主的贴子,像这类问题也比较容易解决:动态代理
不同微服务中使用同一个领域模型是正常的,但不同微服务中根据自身的技术特性,对模型也会有不同的技术型定义,这是很正常的需求。

解决方法:在能用的 JAR 中通过 Java Interface 定义领域模型,JPA 中只是实现这个 Interface,其它的微服务只看到 Java Interface,在不同微服务之间进行模型传递时,通过一个动态代理的对象工厂创建这个接口的实例。

这样就可以不需要在所有的微服务中看到 JPA 的 Entity 了,它们看到的只有领域模型的 Interface,只不过需要定义好对象传输的协议,和反序列化的逻辑。
chenshun00
2020-11-30 09:44:46 +08:00
BeanUtils.Copy(source,target)
Aresxue
2020-11-30 15:40:08 +08:00
问题的原因就是你把 DO 和 DTO 变成一个了,这种做法本身是有点问题,但非要这么做也没事,client 包依赖 JPA 然后 JPA 的依赖变成 provided,实际 run 的应用中也有要 JPA 的依赖,两个依赖版本要尽量保持一致
Joker123456789
2020-11-30 16:11:37 +08:00
正确的做法就是维护两个类,所以不用改。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/730222

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX