javascript
Spring中的Advice类型及其应用
http://blog.csdn.net/myyate/article/details/1822150
在Spring中,Advice都是通過Interceptor來實(shí)現(xiàn)的,主要有以下幾種:
1. 環(huán)繞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;
????}
}
?
????? 環(huán)繞advice類似一個(gè)攔截器鏈,這個(gè)攔截器鏈的中心就是被攔截的方法。在程序(1)(2)我們可以加入我們自己的代碼,以表示在方法執(zhí)行前后我們需要干什么。invocation.proceed()方法運(yùn)行指向連接點(diǎn)的攔截器鏈并返回proceed()的結(jié)果。
2. Before Advice
?
public?interface?MethodBeforeAdvice?extends?BeforeAdvice?{????void?before(Method?m,?Object[]?args,?Object?target)?throws?Throwable;
}
?
??????? 一個(gè)更簡(jiǎn)單的通知類型是before 通知。它不需要 MethodInvocation對(duì)象,因?yàn)樗皇窃谶M(jìn)入方法之前被調(diào)用。before advice的一個(gè)主要優(yōu)點(diǎn)是它不需要調(diào)用proceed()方法,因此就不會(huì)發(fā)生 無意間運(yùn)行攔截器鏈?zhǔn)〉那闆r。
3. After advice
?
public?interface?AfterReturningAdvice?extends?Advice?{????void?afterReturning(Object?returnValue,?Method?m,?Object[]?args,?Object?target)?throws?Throwable;
}
?
?????? 一個(gè)After advice可以訪問返回值(但不能進(jìn)行修改),被調(diào)用方法,方法參數(shù)以及目標(biāo)對(duì)象。
4.Throws Advice
?
//ThrowsAdvice?是一個(gè)空接口,起標(biāo)識(shí)作用public?interface?ThrowsAdvice?extends?Advice?{
}
//所給對(duì)象必須實(shí)現(xiàn)一個(gè)或者多個(gè)針對(duì)特定類型的異常通知方法,格式如下
afterThrowing([Method],?[args],?[target],?subclassOfThrowable)
//只有最后一個(gè)參數(shù)是必須的。因此異常通知方法對(duì)方法及參數(shù)的需求,方法的簽名將從一到四個(gè)參數(shù)之間變化。
?
?????? 最后還有一個(gè)是introduction advice,這個(gè)我想什么時(shí)候自己?jiǎn)为?dú)做個(gè)例子理解一下。
?????? 做了個(gè)例子如下,想像一個(gè)用戶登錄場(chǎng)景:在登錄之前,我們對(duì)其輸入的用戶名進(jìn)行有效性檢查;登錄成功后,我們記上用戶登錄次數(shù);如果登錄失敗,則進(jìn)行異常處理。實(shí)現(xiàn)代碼如下:
?
package?com.learn.spring.test.advisor;//登錄的業(yè)務(wù)代碼
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();
?????????}
????}
}
?
?
?
//用戶登錄次數(shù)統(tǒng)計(jì)攔截器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>
?
測(cè)試代碼運(yùn)行:
?
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");
????}
}
?
輸出結(jié)果:
?
check?user's?name?is?valid?myyate?passed?check....
myyate?is?logining?system...
Counting?the?login?counts?of?myyate
?
總結(jié)
以上是生活随笔為你收集整理的Spring中的Advice类型及其应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装maven到Eclipse
- 下一篇: Spring 2.0.1 与 BEA W