spring boot 通过 @autowired 或构造器注入将接口实现类绑定到依赖项。核心做法是:定义接口,编写一个带 @component(或 @service)注解的实现类,然后在目标类中声明该接口类型的字段或构造参数,spring 容器会自动查找并注入唯一匹配的实现。

如何注册接口实现类
必须确保实现类被 Spring 管理。最简单的方式是在实现类上添加 @Component 注解,或者在配置类中使用 @Bean 方法返回该实例。如果实现类不在默认扫描路径下,需调整 @ComponentScan 的范围。只有被容器管理的 Bean 才能被注入。

package com.example.demo;
import org.springframework.stereotype.Component;
// 1. 定义接口
public interface UserService {
String getName();
}
// 2. 实现接口并注册为 Bean
@Component // 关键:让 Spring 发现这个类
public class DefaultUserService implements UserService {
@Override
public String getName() {
return "DefaultUser";
}
}
上述代码中,DefaultUserService 实现了 UserService 接口,并通过 @Component 注解自动注册到 Spring 容器中。此时,Spring 已经知道如何将 UserService 类型的依赖解析为 DefaultUserService 的实例。
如何在目标类中注入接口
在需要使用接口的类中,通过 @Autowired 注解标记接口类型的字段,或使用构造器注入。Spring 会根据类型自动从容器中获取已注册的实现类实例。推荐使用构造器注入,因为它更利于测试和保证不可变性。

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final UserService userService;
// 构造器注入方式(推荐)
@Autowired
public OrderService(UserService userService) {
this.userService = userService;
}
public void processOrder() {
// 直接使用接口调用方法
String name = userService.getName();
System.out.println("Processing order for: " + name);
}
}
在 OrderService 中,我们声明了 UserService 类型的依赖。由于容器中只有一个 UserService 的实现(即 DefaultUserService),Spring 会自动将其注入到 OrderService 中。这样,业务逻辑层只依赖接口,而不依赖具体实现,符合依赖倒置原则。
当存在多个实现类时如何选择注入
如果同一个接口有多个实现类被注册为 Bean,Spring 在按类型注入时会抛出 NoUniqueBeanDefinitionException 异常。此时需要使用 @Qualifier 注解指定具体的 Bean 名称,或者使用 @Primary 注解标记首选实现类。这解决了多实现场景下的歧义问题。
package com.example.demo;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class AdminOrderService {
private final UserService userService;
// 指定注入名为 "vipUserService" 的 Bean
public AdminOrderService(@Qualifier("vipUserService") UserService userService) {
this.userService = userService;
}
}
在上述代码中,假设有两个 UserService 的实现:DefaultUserService 和 VipUserService。通过在构造器参数上使用 @Qualifier("vipUserService"),明确告诉 Spring 注入名为 vipUserService 的那个实现类。如果不加限定,Spring 将无法决定注入哪一个,从而报错。











