错误描述如下
Description:
The bean ‘fooServiceImpl’ could not be injected as a ‘geektime.spring.data.datasourcedemo.FooServiceImpl’ because it is a JDK dynamic proxy that implements:
geektime.spring.data.datasourcedemo.FooService
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
今天练习Spring事务demo,发现其中有一部分注入了个接口对象???我小声嘀咕:接口不是不能创建对象吗??怎么回事??不仅创建了对象,还能调用被实现的方法中重写覆盖方法体???
所以我把接口对象fooService换成了接口的实现类对象fooServiceImpl,然后报错如上标题
解决方法
那我查了网上相关内容,发现这是AOPJDK动态代理中的内容。虽然注入的是接口对象,但代理实际的是唯一的实现类对象。
唯一的???
那我再次实现接口,弄出另一个类会怎样??
果然报错如下
那我只需使用注解@Qualifier(" ")中指定Bean名称就可以了
或者还有一种方法,
按照错误提示,在EnableTransactionManagement注解中添加proxyTargetClass为true,表示使用cglib代理
同样程序也正常使用了。。。
总结
使用注解 @EnableTransactionManagement 开启事务支持
mode = AdviceMode.PROXY或mode = AdviceMode.ASpectJ
proxyTargetClass默认为false
@Transactional注解
rollbackFor
该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:
指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
cglib代理概念:
动态代理也有个约束:目标对象一定是要有接口的,没有接口就不能实现动态代理……----->因此出现了cglib代理
cglib代理也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能