發現問題:
之前用springAOP做了個操作日志記錄,這次在往其他類上使用的時候,service一直注入失敗,找了網上好多內容,發現大家都有類似的情況出現,但是又和自己的情況不太符合。后來總結自己的情況發現:方法為private修飾的,在AOP適配的時候會導致service注入失敗,并且同一個service在其他的public方法中就沒有這種情況,十分詭異。
解決過程:
結合查閱的資料進行了分析:在org.springframework.aop.support.AopUtils中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) { if (!pc.getClassFilter().matches(targetClass)) { return false ; } MethodMatcher methodMatcher = pc.getMethodMatcher(); IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null ; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Iterator it = classes.iterator(); it.hasNext();) { Class clazz = (Class) it.next(); Method[] methods = clazz.getMethods(); for ( int j = 0 ; j < methods.length; j++) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(methods[j], targetClass, hasIntroductions)) || methodMatcher.matches(methods[j], targetClass)) { return true ; } } } return false ; } |
此處Method[] methods = clazz.getMethods();
只能拿到public方法。
execution(* *(..))
可以匹配public/protected的,因為public的有匹配的了,目標類就代理了,,,再進行切入點匹配時也是能匹配的,而且cglib方式能拿到包級別/protected方法,而且包級別/protected方法可以直接通過反射調用。
private 修飾符的切入點 無法匹配 Method[] methods = clazz.getMethods();
這里的任何一個,因此無法代理的。 所以可能因為private方法無法被代理,導致@Autowired不能被注入。
修正辦法:
1、將方法修飾符改為public;
2、使用AspectJ來進行注入。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/lcngu/p/6246950.html