🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝
一、问题描述
新增一个功能需求后,项目无法启动成功,报错如下
2024-03-11 11:40:08.630 [main] ERROR o.s.b.diagnostics.LoggingFailureAnalysisReporter - [report,40] -
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'userInfoBaseMapper' could not be injected as a 'com.test.mapper.UserInfoBaseTwoMapper' because it is a JDK dynamic proxy that implements:
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
二、原因分析:
根据Idea中的处理意见,发现还是不明白其中的原理。我也只用了@Resource
注解而已,所以我将注解修改为@Autowired
就可以启动正常
了,为什么呢?
在我的印象中他两的区别,有多个同类型的Bean时@Resource 更加简单,如下,怎么会引起报错呢?
// 使用@Resource
@Resource(name = "myBean")
private MyBean myBean;
// 使用@Autowired
@Autowired
@Qualifier("myBean")
private MyBean myBean;
那么首先从两者的区别来研究:首先要清楚,@Resource和@Autowired 注入原理到底有什么区别
2.1 注入原理:
@Autowired
首先按照类型进行注入
- 如果spring容器中
存在同一个类型的多个bean
,那么此时在进行注入的时候按照属性的名称
进行注入
@Resource
- @Resource 可以按照名称或者类型进行注入。
默认按照名称进行匹配
看到这里恍然大悟,原来是@Resource导致的错误
因为@Autowired默认按类型装配,而
@Resource优先按名称
装配,如果使用@Resource 注入userInfoBaseMapper
,而项目中有另外一个bean叫userInfoBaseMapper
,就会出现这个错误。
两个不同的引用,用了同一个名字,导致注入错误。
三、解决方案
3.1 第一种
- 使用
@Autowired
, - 首先按照类型进行注入,存在同一个类型的多个bean,则按照名称注入,则不存在冲突
@Autowired
private UserInfoBaseTwoMapper userInfoBaseMapper;
3.2 第二种
-
@Resource注解不变(默认按照名称进行匹配),
-
修改变量名
,使变量名不与其他类型相同,这里将userInfoBaseMapper
改为userInfoBaseTwoMapper
则启动正常
@Resource
private UserInfoBaseTwoMapper userInfoBaseTwoMapper;