java - 为什么@Validated + @Component + 实现在spring boot中导致类型误导错误?
问题描述
这里的代码示例列表:
根据
@Validated
@Component
public class MyImpl1 {}
@Validated
@Component
public class MyImpl2 {}
@Service
public MySelector {
private final MyImpl1 myImpl1;
private final MyImpl2 myImpl2;
@Autowired
public MySelector(MyImpl1 myImpl1, MyImpl2 myImpl2) {
this.myImpl1 = myImpl1;
this.myImpl2 = myImpl2;
}
public Object select (Long id) {
switch (id) {
case 1:
return myImpl1;
case 2:
return myImpl1;
}
}
}
这有效:注入bean,这里没问题。这里的重要说明是MyImpl
bean是代理,这对于自动装配没有问题。
但是当我这样添加时,事情变得不同implements
了:
工具
@Validated
@Component
public class MyImpl1 implements MyInterface{}
@Validated
@Component
public class MyImpl2 implements MyInterface{}
public interface MyInterface {}
@Service
public MySelector {
private final MyImpl1 myImpl1;
private final MyImpl2 myImpl2;
@Autowired
public MySelector(MyImpl1 myImpl1, MyImpl2 myImpl2) {
this.myImpl1 = myImpl1;
this.myImpl2 = myImpl2;
}
public Object select (Long id) {
switch (id) {
case 1:
return myImpl1;
case 2:
return myImpl2;
}
}
}
我在这里得到:
Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'myImpl1' is expected to be of type 'MyImpl1' but was actually of type 'com.sun.proxy.$Proxy108'
如果我删除@Validated
每一个重新开始工作。
我知道spring使用代理,最好使用接口。但我不明白为什么我在这里遇到问题?如果 spring可以通过类名自动装配代理,为什么在添加时它不能这样做,implements
特别是当这个接口没有用于自动装配字段时。
更新
spring-boot 版本是2.0.3
spring-core 版本是5.0.7.RELEASE
解决方案
使用接口 JDK 动态代理(基于接口),否则您使用基于类的代理。较新的 Spring Boot 版本强制始终使用基于类的代理。无论哪种方式,它都使用代理,但对于接口,它只使用接口代理,否则使用基于类(CGLIB)的代理。
这是真的,添加接口会导致 jdk 代理不是原始类的子类。
要强制子类代理子类,请将以下内容添加到 bean 声明中:
@Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
例如:
@Validated
@Component
@Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class MyImpl2 implements MyInterface{}
推荐阅读
- javascript - 如何计算具有最大值的更改滑块值?
- reactjs - 类型“{}”缺少类型中的以下属性 - TS 错误
- android - 在 avd 管理器中禁用停止选项
- python - BASIC PYTHON - 不同变量的相同结果
- c++ - 在 SSE/AVX 中高效计算 X 的幂
- node.js - 我在同一个文件上使用了两次 fs.readFile() 但它说它不同?
- css - 输入焦点道具不适用于样式化组件中的标签
- java - 检查子树?
- lua - 尝试使用“CameraMaxZoomDistance”索引 nil 我尝试搜索解决方案,但没有找到一个
- android - 预期 BEGIN_OBJECT 但为 BEGIN_ARRAY 但 json 响应已经有一个对象