問題:
The bean 'xxx' could not be injected as a 'com.github.service.xx' because it is a JDK dynamic proxygit
先說說問題的來源吧,當前這個問題是我在springboot配置事務時出現的,原本我搭建了一個springboot的web框架後,啓動事務配置只須要以下兩步便可完成:
1.在啓動類Application類上設置@EnableTransactionManagement,表示啓動springboot事務支持
2.在Service層的實現類中指定的方法上設置@Transactional
以上簡單的兩步便可完成,但恰恰在啓動後會報如上錯誤。經過觀察控制檯報錯的緣由以下:
Console描述1:
Description:github
The bean 'userServiceImpl' could not be injected as a 'com.ysq.springboot.service.Impl.UserServiceImpl' because it is a JDK dynamic proxy that implements:
com.ysq.springboot.service.UserServiceweb
根據上面描述,它是在個人Action層中,注入userServiceImpl這個Bean時失敗,(失敗的緣由就是我有實現接口,而springboot的事務默認是使用jdk的動態代理,即基於接口))。到這裏我忽然明白了,在action層中我注入的Bean是實現類,所以就會報錯。因而我將此注入Bean的方式改爲了其接口,問題迎刃而解。
Console描述2:
Action:spring
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.
在看上面的描述它給了咱們解決此問題的方案,說你能夠考慮下將action中注入的Bean改爲接口方式或者強迫事務使用CGLib代理方式(基於類,即設置proxyTargetClass=True在啓動事務管理上@EnableTransactionManagement(proxyTargetClass=True)),這種以CGLib代理方式進行,按照以前寫法,咱們應該是須要引入相應的cglib庫的jar包。而在springboot中已經集成了。但在spring3.2以前是須要引入的;springboot
假如你是在不想將注入的Bean改爲接口方式,非得要用實現類,並且還不想再啓動事務時配置proxyTargetClass=true,那麼接下來讓你知道什麼叫厲害,有以下方法:
在你Service層對應的實現類上配置@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)註解,代表此類上全部方法上的事務都是CGLib方式代理的,問題照樣能夠解決。(參考:https://blog.csdn.net/z394642048/article/details/84759331)框架
寫在最後:這裏我須要強調一點,就是網上有些解決此問題都說在properties文件中設置spring.aop.proxy-target-class=true。你要搞清楚咱們的問題是在開啓springboot事務時出現的哦,雖然和AOP代理過程產生的問題同樣,但解決的方式不一樣額。ide
參考文獻:
https://github.com/alibaba/druid/issues/2330
https://blog.csdn.net/m0_38016299/article/details/78390363ui