zoukankan      html  css  js  c++  java
  • 当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,

  • 相关阅读:
    [HDOJ4788]Hard Disk Drive(水题)
    [HDOJ4782]Beautiful Soup(模拟)
    [HDOJ3652]B-Number(数位dp)
    [CF55D]Beautiful numbers(数位dp,状态压缩)
    [HDOJ3555]Bomb(数位DP)
    [HDOJ2089]不要62(数位DP)
    [HDOJ5881] Tea(找规律)
    [HDOJ5900]QSC and Master(区间dp)
    [HDOJ5878]I Count Two Three(暴力枚举,二分)
    [HDOJ5879]Cure(求极限,打表)
  • 原文地址:https://www.cnblogs.com/zengyou/p/3152395.html
Copyright © 2011-2022 走看看