当autowired 碰到transactional

今天碰到一个很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 2013-06-24 14:38 yoyo_zeng 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/zengyou/p/3152395.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值