我是一个 Java 程序员,用 spring boot 框架,常常会用 @Autowired 注解去引入各种 service 或者 mapper 我觉得很麻烦呀,有没有不通过 @Autowired 或者我引入一个 baseService 就引入了所有的 bean 。
我想所有的注册 bean 都会到 spring boot 进行管理,那么为什么 spring boot 不提供一个默认引入所有,然后想用什么就用什么,不用每个都要 @Autowired 一下。
当然我不是说从 spring boot 上下文通过 getBean 的方式去拿,那样太不优雅了。
有没有这样比如举一个列子 这是我想要的😍
@Component
public class ServiceB {
@Autowired
private BaseService baseService;
public Order void queryOrder() {
User user = baseService.UserSerice.getUser();
Order order = baseService.OrderService.getOrderByUserId(user.getId());
return order;
}
}
引入我感觉有时候业务超级复杂,然后慢慢的会变成 @Autowired 地狱,比如会有这样的情况
这是不是我想要的😨
@Component
public class ServiceB {
@Autowired
private UserSerice userSerice;
@Autowired
private OrderService orderService;
public Order void queryOrder() {
User user = userSerice.getUser();
Order order = orderService.getOrderByUserId(user.getId());
return order;
}
}
这个随便写的,就是举个列子
1
forbreak 2023-08-02 14:29:56 +08:00
那你把 getBean 封装下,做成动态生成,就能达到你要的效果了吧。
|
2
csw3983931 OP @forbreak 要代码提示。比如我输入 baseService.U 要提示 baseService.UserSerice ,感觉通过 Lombok 提前生成一个类,把所有的 bean 都放进去,感觉应该可行
|
3
oneisall8955 2023-08-02 14:45:24 +08:00
100%循环依赖
|
4
csw3983931 OP @oneisall8955 是的 🤣
|
5
arvinsilm 2023-08-02 14:50:56 +08:00
这和用上下文去拿有什么区别?
你可以自己写个 BaseService ,再搞个自动生成,把所有 Service 都在 BaseService 里实现一个返回方法。 |
6
mgzu 2023-08-02 14:56:16 +08:00
弊大于利,依赖关系不够清晰,循环依赖
|
7
csw3983931 OP @arvinsilm getBean 去拿感觉比较繁琐,每次都要 context.getBean(ServiceB.class)
|
8
gogo789 2023-08-02 15:26:36 +08:00
看问题感觉你就是想干掉 autowired 。spring 提供依赖注入和依赖查找,autowired 只能说是依赖注入的一种方式,你说的可以通过依赖查询解决就是 BeanFactory.getBean ,但是你觉得不优雅,那就换一个依赖注入的方式,直接用构造器注入,这样就不用写 autowired 了,结合 lombok 的注解的话更方便。
|
9
kingstar718 2023-08-02 15:29:48 +08:00
@gogo789 同意,使用 lambok 的 @RequiredArgsConstructor 注解在类上,引入 bean 直接就是 private final xxService
|
10
gogo789 2023-08-02 15:30:09 +08:00
不太建议你搞一个包含所有 bean 的 baseService ,因为 BeanFactory 干的就是这个事,你没必要自己再封装一层
|
11
rs9G7IrdOdiNR3h1 2023-08-02 15:31:13 +08:00 1
我也有一个奇思妙想。能不能一行代码实现我老板的所有需求。
|
12
bruce0 2023-08-02 15:35:04 +08:00
偏个楼 Autowired 真的是一个 V 站用户, 能被 @ 到🤣🤣🤣
|
13
yule111222 2023-08-02 15:36:54 +08:00
你不如换个想法,把你这些 service 的方法都变成 static 的,没开玩笑
|
15
newaccount 2023-08-02 17:19:59 +08:00
1. 全部引入,循环逃不掉,没得耍
2. 既然你知道用 lombok ,那么为什么不在 service 头上直接一个 @ RequiredArgsConstructor 了事儿 3. service 作为业务节点,如果需要 service 相互引用,嗯,大部分情况是设计出了问题 |
16
nothingistrue 2023-08-02 17:34:36 +08:00
对于楼主本身,11 楼 whooami 的回复就足够了。
然后从技术上面说一下。 第一个层面,假如只是不想要 @Autowired ,但是还保留成员变量定义。那么你是必须留着 @Autowired 的,因为并不是所有的成员变量都是自动注入的(尤其是有状态 Bean 的时候)且没有什么好的约定能代替配置来区分它们,所以你必须显式的声明它要被自动注入。当然也不是没有替代措施,当你定义了构造器的时候,那就有了通过构造器自动注入的约定,这时候就可以省略掉 @Autowired 这个显式声明。构造器自动注入,也是 Spring 官方推荐的自动注入方式,但是构造器注入的可读性,不如直接在成员变量上声明 @Autowired 好。 在第一个层面,恰恰相反,必要的显式声明 @Autowired 不是地狱,隐式强制对 Bean 的所有成员变量做自动注入,才是地狱。 第二个层面,假如是连成员变量定义都不想定义,继承 baseService 就能自动引入所有 Bean 。这本质上相当于把所有 Bean 整合成同一个类型了,已经将 Java 返祖成原始的 C 了,根本无法作出技术回复。 |
17
yesterdaysun 2023-08-02 18:18:48 +08:00
我大概能理解 OP 的思路, 很多年前我做一个 C#的项目的时候, 那时候是架构师自己搭的框架, 思路就是所有的 Service 放到一个静态类里面, 比如叫 ApplicationServiceManager, 简称 ASM, 任何时候要用的时候直接 ASM.UserService.GetUser()就行, 其实用起来也挺爽的, 要用的是时候直接 ASM 点 XXX 出来所有的 Service, 当时架构找呢么解决初始化和循环依赖的我已经忘了, 但是至少这条路是可行的
但是我还是觉得这套思路和现行的 Spring 体系不太搭, 就像楼上说的, 现在只要用 lombok 配合构造器注入, 几乎是无感的引入需要的 Service, 感觉挺简洁的, 那套集中式的 Service 管理感觉要自己在底层架构引入很多额外的约定和设计才能做出来, 感觉也比较重, 也不利于代码维护和单元测试 总之相比之下我还是偏向普通 Spring 的注入体系 |
18
minamike 2023-08-02 18:22:22 +08:00 via iPhone
为什么不问问神奇的 ChatGPT 呢
|
19
xausky 2023-08-03 09:23:52 +08:00
有依赖地狱就是本身设计的不好,一般多个分层从 controller 到 mapper 中间不管多少层调用的时候一定得是从上到下的,平级调用要谨慎,逆向调用要禁止。你如果是我管不,我就是要我想要的这个方案,那么你直接全部注入 ApplicationContext 然后 getBean 就好了。
|