springboot开发明明调用的是接口里面的方法为什么执行的却是接口对应实现类里面的方法?
Spring Boot 中的依赖注入使用的是动态代理技术。在实例化接口的时候,Spring Boot 会自动为这个接口创建一个代理对象,代理对象会拦截所有对接口方法的调用,并将调用转发给实现类。
具体来说,Spring Boot 会为每个使用了 @Service、@Component 等注解的类创建一个代理对象。当我们在其他类中使用 @Autowired 注解注入某个接口的时候,实际上注入的是这个接口的代理对象,而不是直接的实现类。
代理对象会在实际调用方法前进行一些处理,例如:进行安全检查、事务管理等操作。然后才会将方法调用转交给实现类。
在这个过程中,Spring Boot 会根据默认规则来选择具体的实现类。如果有多个实现类,可以通过 @Primary 注解或者 @Qualifier 注解来进行指定。
需要注意的是,在使用动态代理技术时,只有接口中声明的方法才会被拦截。如果实现类中定义了接口中未声明的方法,那么这些方法就无法通过代理对象来调用。
@Autowired自动装配时,要是一个接口有多个实现类怎么办?
在 Spring Boot 开发中,通常我们使用依赖注入的方式来调用接口里面的方法,也就是说我们不需要关心具体的实现类是哪一个,而是通过接口进行调用。但是,对于多个实现类的情况,如果要选择其中一个实现类进行调用,就需要明确指定使用哪个实现类。下面是一些可行的解决方案:
1.通过@Qualifier 注解指定具体的实现类 在 Spring Boot 中,可以使用 @Qualifier 注解来指定具体的实现类。例如,假设接口 MyService 有两个实现类 MyServiceImplA 和 MyServiceImplB,那么你可以在调用的地方使用类似下面的代码进行指定:
@Autowired
@Qualifier("MyServiceImplA")
private MyService myService;
这样在调用 MyService 接口方法时,就会使用 MyServiceImplA 中的实现。
2.使用 @Primary 注解标注首选的实现类 在 Spring Boot 中,可以使用 @Primary 注解标注某个实现类为首选的实现类,这个实现类在使用 @Autowired 注解时会自动被注入。例如:
@Service
@Primary
public class MyServiceImplA implements MyService {
// 实现类 A 的具体实现
}
@Service
public class MyServiceImplB implements MyService {
// 实现类 B 的具体实现
}
这样,当使用 @Autowired 注解时,就会优先注入 MyServiceImplA 类的实例。如果需要使用其他实现类,则可以通过 @Qualifier 注解进行指定。
当然,在 Spring Boot 中,还有很多其他的方式来选择具体实现类。选择哪种方式可以根据项目的需求、开发团队的习惯来决定。
3.@Mapper有什么作用
@Mapper注解是由Mybatis框架中定义的一个描述数据层接口的注解,用于告诉sprigng框架此接口的实现类由Mybatis负责创建,并为这个接口创建一个代理对象,然后将其代理对象存储到spring容器中。