【发布时间】:2020-05-26 10:49:42
【问题描述】:
我有以下情况:
@Service
interface OrderingService {
}
public class DefaultOrderingService implements OrderingService {
}
@RestController
public class DefaultOrderingRestController {
private final OrderingService orderingService;
public DefaultOrderingRestController(OrderingService orderingService) {
this.orderingService = orderingService;
}
}
我希望 Spring 通过扫描代码自动连接接口的唯一实现。这可能吗?
换句话说,目前这个问题有两种解决方案,我想问是否还有第三种:
- 将
@Service声明从接口OrderingService移动到实现DefaultOrderingService - 在Configuration中,定义具体的Bean如下:
@Configuration
public class DefaultConfig {
@Bean
public OrderingService orderingService() {
return new DefaultOrderingService();
}
}
问题:是否可以让 Spring 自动扫描(然后 Spring 仅找到 OrderingService 的一种实现)和自动装配?如果是,该怎么做? 如果不是,这不是一个好习惯吗?为什么?
【问题讨论】:
-
将
@Service注释放在接口上是错误的,它属于实现(您的解决方案#1)。解决方案 #2 也可以。为什么需要第三种解决方案?只需选择 #1 或 #2 即可。如果没有定义为 Spring bean(通过@Service或@Component注释或 Spring 配置中的其他方式),则无法让 Spring 自动获取实现。 -
您可以进行自己的组件扫描,如果您发现接口只有一个实现,请将其注册到应用程序上下文中
-
@Autowired这样做,对吗?我的意思是,如果只有一个实现,Spring autowires 它。只有当有多个实现时,Springs 才会抛出歧义错误。而且,这就是@Qualifier出现的时候。那么,你为什么不选择@Autowired? -
@RoyalBg 有趣的建议
-
不,如果只有一个实例,弹簧自动装配。你可以有任何实现,但在运行时只有一个实例,或者你必须使用 Primary annotation 的 Qualifier。