今天碰到一个很sb的bug。
起因是:
@Controller public class DemoController { @Autowired private DemoService demoService; } @Service public class DemoService{ @Autowired private DemoRepository demoRespository; @Transactional public void addUser(UserInfo userInfo){ demoRespository.addUser(userInfo); } } //以上 run ok,然后我改为: @Controller public class DemoController { @Autowired private IDemoService demoService; } @Service public class DemoService implements IDemoService{ @Autowired private DemoRepository demoRespository; @Transactional public void addUser(UserInfo userInfo){ demoRespository.addUser(userInfo); } } //===总是报无法注入的bug, not such bean之类的。不应该啊! //===后来发现我个sb在另外一个controller中也用了DemoService,改为IDemoService就可以了 @Controller @RequestMapping(value="/user") public class UserController { @Autowired private DemoService demoService; }
在解决这个问题中,查找了一些相关资料,
DemoService无法注入的解释是:如果有Transactional,spring会生成一个proxy class, implements IDemoService,类似:
public class ProxyServiceImpl implements IDemoService { private DemoService demoService; //instance of OriginalDaoImpl public void addUser(Object o){ try{ transaction.start(); demoService.addUser(o); transaction.commit(); }catch(Exception e){ transaction.rollback(); }finally{ //clean up code } } }
所以注入必须是interface。
还有一种办法:
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" /> //添加 proxy-target-class="true" 这样可以直接注入 @Controller public class DemoController { @Autowired private DemoService demoService; }
解释是:
<tx:annotation-driven/>
元素的 "proxy-target-class
" 属性值来控制是基于接口的还是基于类的代理被创建。
如果 "proxy-target-class
" 属值被设置为 "true
",那么基于类的代理将起作用(这时需要CGLIB库cglib.jar在CLASSPATH中)。如果 "proxy-target-class
" 属值被设置为 "false
" 或者这个属性被省略,那么标准的JDK基于接口的代理将起作用。
以上两种方法二选一,要不用第一种,不配置 "proxy-target-class"属性,代理基于接口,必须注入interface,
第二种:配置 "proxy-target-class" 属性 为true,代理基于类,注入class,
标签:
spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?