問題:看了不少關於Spring AOP的文章,在講各類切入方式(before、around、after-returnning、thrown等)時,被切入的業務主體Bean的方法,基本都是無參數的。
也有提到有參數的,但都是一個String型的參數。
以before爲例,無參數方法的切點配置爲 java
若是方法有一個String型的參數param,則配置爲 spring
注:若是參數其實可爲任何類型,即Object。若是非要強調是String型,參數爲其餘類型的方法,不想被切點切入,則可寫成 method="before(java.lang.String)"
(經實際測試 arg-names="param" 不寫也能夠)
但若是 cn.xxxx..*.* 的方法有多個參數,且個數不定,要想讓切點能夠切入,這麼個寫法就不行了。
我搜了N多的帖子,也沒能找到方法,最終幾經展轉,終於在網友的幫助下,點破了這一層窗戶紙,其實也很簡單,仍是在配置的寫法: 測試
與之配合的切點的寫法是 spa
這樣,不論業務Bean的方法有多少個參數,均可以被這個切點切入了。若是須要訪問各個參數,只需 xml
----------------------------------華麗的分割線-----------------------------------
其實,可以知足如上需求的方法,至少還有一種,就是攔截器。
blog
思路是在注入ServiceBean時,偷樑換柱一下,用myService代替,實際是指向Spring的攔截器,它能夠在執行真正的ServiceBean以前,先執行beforeInterceptor所指向的攔截代碼
(這裏是MyChecker,這個攔截器要實現org.aopalliance.intercept.MethodInterceptor接口, 並完成public Object invoke(MethodInvocation invocation) throws Throwable方法)而後再交還給target屬性指明的真正的ServiceBean。它不單單可以獲得方法的參數,並且還有更強的功能——決定是 否繼續執行target。 接口
看到了吧,這裏不單單能夠獲得目標方法的參數 Object[] args = invocation.getArguments();
還能夠,控制是否要繼續執行目標方法,仍是阻斷。所以用來作認證是再合適不過了。
----------------------------------華麗的分割線-----------------------------------
爲何要加入兩條分割線之間的之一段呢?除了也做爲before切入的另外一種實現方式,更主要的是想引出下面的問題:
我發現,在我成功的用AOP切入以後,每次都執行了兩遍切點,且我檢查了配置文件,並無重複定義<AOP>
當我在切點代碼中加入 get
我發現,這個target有一次是個人ServiceBean,而另外一次是相似$Proxy22之類的東西。這才恍然大悟,它應該是那個攔截器!也就是說,攔截器被切點切入了一次,真正的target又切入了一次。
顯然,從配置文件的寫法上彷佛是沒法避免攔截器被切入的(雖然org.springframework.aop.framework.* 並非切面),那隻能在切點裏想辦法迴避了 博客
至此,可讓多參數方法被切入的before切點完成了。
(after-returnning沒有遇到什麼障礙,多參數也很簡單,甚至不用在pointcut配置中聲明,還可取到返回值) string
切點,能夠同時獲得JoinPoint和返回值
最後,不知道哪位曉得,若是經過AOP而不是中間段落中提到的【攔截器】,來實現現有攔截器的功能,即取得入口參數,並能夠控制繼續執行被切的業務ServiceBean,仍是阻止它執行。