because it is a JDK dynamic prox
2019-11-19 本文已影响0人
edgar_chan
The bean 'A' could not be injected as a 'xxx.BClassName' because it is a JDK dynamic proxy that implements:
CInterface
搜索了几篇文章,都是在说通过proxy-target-class=true或者transactional等来解决;解决办法要么跟问题本身属于弱有关,要么属于曲线救国。
这个问题其实我们不妨大胆直面它,因为日志信息已经说得比较直白了,我们来翻译一下:
bean实例A不能被当作B类用于注入,因为B类是一个实现了C接口的jdk动态代理
jdk动态代理和C接口放在一起描述,说明什么呢?说明它在强调此动态代理是面向接口的,不是面向java类的!
因此它认为不能作为java类来注入到其他对象中;
为什么不能呢?
因为jdk动态代理对类进行包装后,原生类隐藏了(->target),冒出来一个只代表接口实现的新生类;即接口申明的方法,新生类才会有。
如果你执意要以此新生类注入至其他bean实例,那么在runtime过程中,可能因为你调用的方法未在接口中声明而抛出异常;
为什么异常?因为新生类中压根就没有此方法。
而且这是在编译时不能被发现的,所以spring帮你预先防御,在启动时抛错,而不会等到运行时。
所以解决办法如下:
@Autowired
@Qualifier("A")
CInterface b;
如果需要用到未在C接口中声明的类本身的方法,可以从b中取出原生类实例进行调用。