javascript
Spring中的Advice类型及其应用
http://blog.csdn.net/myyate/article/details/1822150
在Spring中,Advice都是通過Interceptor來實現的,主要有以下幾種:
1. 環繞Advice:
?
//例子摘自Spring reference public?interface?MethodInterceptor?extends?Interceptor?{??????Object?invoke(MethodInvocation?invocation)?throws?Throwable;
}
public?class?DebugInterceptor?implements?MethodInterceptor?{
????public?Object?invoke(MethodInvocation?invocation)?throws?Throwable?{
????????System.out.println("Before:?invocation=["?+?invocation?+?"]");? //(1)
????????Object?rval?=?invocation.proceed();
????????System.out.println("Invocation?returned");? //(2)
????????return?rval;
????}
}
?
????? 環繞advice類似一個攔截器鏈,這個攔截器鏈的中心就是被攔截的方法。在程序(1)(2)我們可以加入我們自己的代碼,以表示在方法執行前后我們需要干什么。invocation.proceed()方法運行指向連接點的攔截器鏈并返回proceed()的結果。
2. Before Advice
?
public?interface?MethodBeforeAdvice?extends?BeforeAdvice?{????void?before(Method?m,?Object[]?args,?Object?target)?throws?Throwable;
}
?
??????? 一個更簡單的通知類型是before 通知。它不需要 MethodInvocation對象,因為它只是在進入方法之前被調用。before advice的一個主要優點是它不需要調用proceed()方法,因此就不會發生 無意間運行攔截器鏈失敗的情況。
3. After advice
?
public?interface?AfterReturningAdvice?extends?Advice?{????void?afterReturning(Object?returnValue,?Method?m,?Object[]?args,?Object?target)?throws?Throwable;
}
?
?????? 一個After advice可以訪問返回值(但不能進行修改),被調用方法,方法參數以及目標對象。
4.Throws Advice
?
//ThrowsAdvice?是一個空接口,起標識作用public?interface?ThrowsAdvice?extends?Advice?{
}
//所給對象必須實現一個或者多個針對特定類型的異常通知方法,格式如下
afterThrowing([Method],?[args],?[target],?subclassOfThrowable)
//只有最后一個參數是必須的。因此異常通知方法對方法及參數的需求,方法的簽名將從一到四個參數之間變化。
?
?????? 最后還有一個是introduction advice,這個我想什么時候自己單獨做個例子理解一下。
?????? 做了個例子如下,想像一個用戶登錄場景:在登錄之前,我們對其輸入的用戶名進行有效性檢查;登錄成功后,我們記上用戶登錄次數;如果登錄失敗,則進行異常處理。實現代碼如下:
?
package?com.learn.spring.test.advisor;//登錄的業務代碼
public?interface?LoginService?{
????void?login(String?name,?String?password)?throws?UnauthorityException;
}
public?class?LoginServiceImpl?implements?LoginService?{
????public?void?login(String?name,?String?password)?throws?UnauthorityException?{
??????????? check(name,?password);
??????????? System.err.println(name?+?"?is?logining?system...");
????}
????
????private?void?check(String?name,?String?password)?throws?UnauthorityException?{
??????????? if("myyate".equals(name)?&&?"pass".equals(password)?)?{
???????????????????? System.err.println(name?+?"?passed?check....");
??????????? }?else?{
??????????????????? throw?new?UnauthorityException("invalid?password");
??????????? }
????}
}
?
?
?
//用戶名檢查 攔截器 public?class?LoginNameCheckInterceptor?implements?MethodBeforeAdvice?{????public?void?before(Method?method,?Object[]?args,?Object?target)?throws?Throwable?{
???????? System.err.println("check?user's?name?is?valid?");
???????? if(args[0]?==?null?||?"".equals(args[0].toString().trim()))?{
?????????????? throw?new?IllegalArgumentException();
?????????}
????}
}
?
?
?
//用戶登錄次數統計攔截器public?class?LoginCountInterceptor?implements?AfterReturningAdvice?...{
????public?void?afterReturning(Object?returnValue,?Method?method,?Object[]?args,?Object?target)?throws?Throwable?...{
????System.err.println("Counting?the?login?counts?of?"?+?args[0]);
????}
}
?
?
?
//異常處理攔截器 public?class?ExceptionThrowInterceptor?implements?ThrowsAdvice?{????
????public?void?afterThrowing(Method?m,?Object[]?args,?Object?target,?IllegalArgumentException?ex)?throws?Throwable?{
????System.err.println("Login?name?is?wrong,?exception:?"?+?ex);
????}
????
????public?void?afterThrowing(Method?m,?Object[]?args,?Object?target,?UnauthorityException?ex)?{
???????System.err.println(target.getClass()?+?"."?+?m.getName()?+?
???????????"()?throw?a?exception:?"?+?ex.getMessage());
????}
}
?
配置文件如下:
?
<?xml?version="1.0"?encoding="UTF-8"?><beans?xmlns="http://www.springframework.org/schema/beans"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xmlns:aop="http://www.springframework.org/schema/aop"
????xmlns:tx="http://www.springframework.org/schema/tx"
????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
???????????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
???????????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
????<bean?id="loginServiceTarget"
????????class="com.learn.spring.test.advisor.LoginServiceImpl"/>
????????
????<bean?id="loginNameCheckInterceptor"
????????class="com.learn.spring.test.advisor.LoginNameCheckInterceptor"/>
????????<!--?
????<bean?id="loginCheckInterceptor"
????????class="com.learn.spring.test.advisor.LoginCheckInterceptor"/>
?????????-->
????<bean?id="loginCountInterceptor"
????????class="com.learn.spring.test.advisor.LoginCountInterceptor"/>
????<bean?id="exceptionThrowInterceptor"
????????class="com.learn.spring.test.advisor.ExceptionThrowInterceptor"/>
????????
????<bean?id="loginService"?class="org.springframework.aop.framework.ProxyFactoryBean">
????????<property?name="target"><ref?local="loginServiceTarget"/></property>
????????<property?name="proxyInterfaces">
????????????<list>
????????????????<value>com.learn.spring.test.advisor.LoginService</value>
????????????</list>
????????</property>
????????<property?name="interceptorNames">
????????????<list>
????????????????<value>loginNameCheckInterceptor</value>
????????????????<value>loginCountInterceptor</value>
????????????????<value>exceptionThrowInterceptor</value>
????????????</list>
????????</property>
????</bean>
</beans>
?
測試代碼運行:
?
public?class?Test?{????public?static?void?main(String[]?args)?throws?Exception?{
??????? BeanFactory?bf?=?
??????????? BeanFactoryFactory.getBeanFactory("beans.xml",?Test.class);
??????? LoginService?ls?=?(LoginService)?bf.getBean("loginService");
??????? ls.login("myyate",?"pass");
????}
}
?
輸出結果:
?
check?user's?name?is?valid?myyate?passed?check....
myyate?is?logining?system...
Counting?the?login?counts?of?myyate
?
總結
以上是生活随笔為你收集整理的Spring中的Advice类型及其应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装maven到Eclipse
- 下一篇: [Java] Welcome to Ar