Just a little smile ^ ^

yoyo_zeng

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  112 随笔 :: 3 文章 :: 0 评论 :: 10万 阅读

今天碰到一个很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,

posted on   yoyo_zeng  阅读(884)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
点击右上角即可分享
微信分享提示