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,

  • 相关阅读:
    webpack第一节(4)
    webpack第一节(3)
    webpack第一节(2)
    webpack第一节(1)
    node 下载 解压 重命名
    node 文件操作
    js判断设备(转)
    【CSS3】transform-origin以原点进行旋转 (转)
    手机(转)
    mysql最大连接数问题
  • 原文地址:https://www.cnblogs.com/zengyou/p/3152395.html
Copyright © 2011-2022 走看看