轉自我的個人博客:《記一次SpringBoot Aspect不生效解決過程》
問題描述
項目中兩個aspect,一個環繞controller,用於記錄日志,能夠正常在point處進入aspect處理;另一個aspect 的point設於service,死活不能進入。
解決思路
1、首先排查pointcut配置是否正確,檢查后發現沒有問題;
2、我們都知道spring的aop運用的是動態代理技術,由spring托管的bean大多為代理bean,controller層打印service對象,發現service對象竟然直接是service實現類的“本尊”。如下圖所示:
再看springboot啟動日志,發現roleServiceImpl實例化的時候有如下提示:
Bean 'roleServiceImpl' of type [com.gaoxiaobo.wms.service.impl.RoleServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
那么問題就明了了,我們在controller層調用的roleServiceImpl對象非代理對象而是其本身,那么對其的aspect是不會生效的,不僅aspsect不會生效,事務注解@Transactional也不會生效,問題還是相當嚴重的。
那么,why 沒有生成其代理對象呢?一定是哪里先調用了roleServiceImpl導致spring優先實例化了該bean;
通過排查,找到了罪魁禍首:shiro 的LifecycleBeanPostProcessor優先實例化自定義Realm,自定義的Realm依賴於roleService,導致roleService被初始化。
解決方法
自定義realm中roleService設置成懶加載。