和Spring1.X相比,Spring2.X使用AspectJ的語法來聲明AOP,這使得它更“標(biāo)準(zhǔn)”,更靈活了。還是那句話,如果你不了解AspectJ并且打算使用Spring2.X的AspectJ式AOP,那就學(xué)學(xué)AspectJ吧,這方面的書還是很多了。
Spring2.X下的切面有兩種實(shí)現(xiàn)方式,一種是以Java文件定義切面(其只是普通的Java類),然后在配置文件中聲明定義的切面;另一種是在Java類中引入和AOP相關(guān)的元數(shù)據(jù)(注釋)。
先介紹第一種配置方式。需要指出的是,Spring2.X的beans名稱空間和Spring1.X有所不同,它采用了Schema而不是DTD(也可采用DTD方式,具體的請參考文檔)。還是引入毫無意義的日志切面,定義的切面類LogingAspect 如下:
public class LogingAspect {
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}
同時在配置文件中如下配置:
< bean id = " logAspectTarget " class = " hibernatesample.service.util.LogingAspect " >
</ bean >
< aop:config >
< aop:aspect id = " logAspect " ref = " logAspectTarget " >
< aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:after pointcut - ref = " businessService " method = " logMethod " />
</ aop:aspect >
</ aop:config >
對于上面的切面,切入點(diǎn)businessService是在配置文件中聲明的,其表達(dá)式采用了 AspectJ的語法,LogingAspect 類中l(wèi)ogMethod(JoinPoint jp)方法根據(jù)配置文件信息可知其是after通知,方法的JoinPoint參數(shù)不是必須的,它是來自于AspectJ的實(shí)用類,這里用它不過輸出一些和連接點(diǎn)有關(guān)的信息。當(dāng)然,在Spring2.X中,切入點(diǎn)和通知能更靈活的使用,我們可以如AspectJ一樣傳遞參數(shù)給通知。如果需要在Service中引入事務(wù)功能,需要如下配置事務(wù)通知:
< tx:advice id = " txAdvice " transaction - manager = " transactionManager " >
< tx:attributes >
< tx:method name = " get* " read - only = " true " />
< tx:method name = " find* " read - only = " true " />
< tx:method name = " * " />
</ tx:attributes >
</ tx:advice >
< aop:config >
< aop:pointcut id = " demoServiceMethods " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:advisor advice - ref = " txAdvice " pointcut - ref = " demoServiceMethods " />
< aop:aspect id = " logAspect " ref = " logAspectTarget " >
< aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:after pointcut - ref = " businessService " method = " logMethod " />
</ aop:aspect >
</ aop:config >
完成上面的工作相當(dāng)于完成了 Spring1.X 的 自動代理。 我們接下來需要定義的任何 Service Bean 都可以很純粹很純粹了:
< bean id ="accountService" class ="hibernatesample.service.impl.AccountServiceImpl" >
< property name ="accountDAO" ref ="accountDAO" ></ property >
</ bean >
第二種實(shí)現(xiàn) AOP 的方式和第一種相比,只是在 LogingAspect 中加入了注釋,而省去了配置文件中和 LogingAspect 相關(guān)的配置。重新編寫的 LogingAspect 如下:
@Aspect
public class LogingAspect {
@Pointcut( " execution(* hibernatesample.service.*.*(..)) " )
public void businessService(){}
@After( " businessService() " )
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}
而簡化后的配置文件可以去除上面的如下和 logAspect 相關(guān)的配置信息:
< aop:aspect id ="logAspect" ref ="logAspectTarget" >
< aop:pointcut id ="businessService" expression ="execution(* hibernatesample.service.*.*(..))" />
< aop:after pointcut-ref ="businessService" method ="logMethod" />
</ aop:aspect >
< bean id ="logAspectTarget" class ="hibernatesample.service.util.LogingAspect" ></ bean >
還沒有完,為了使 Spring 應(yīng)用 LogingAspect 的注釋,需要在配置文件中添上
<aop:aspectj-autoproxy/>
如果覺得事務(wù)的配置沒有使用注釋更簡潔(我倒不會有這樣的想法,畢竟在配置文件中聲明的事務(wù)只是那么固定的幾段,除非作用于類上的事務(wù)邏輯上很復(fù)雜),也可以使用Spring提供的事務(wù)注釋作用于類文件上,這可是更細(xì)粒度的事務(wù)聲明了。
坦率的說,由于時間有限,該文寫的比較粗糙。對于Spring AOP有興趣并有疑問的朋友,可以參考Spring的文檔,它的文檔做的還是不錯的。
Spring2.X下的切面有兩種實(shí)現(xiàn)方式,一種是以Java文件定義切面(其只是普通的Java類),然后在配置文件中聲明定義的切面;另一種是在Java類中引入和AOP相關(guān)的元數(shù)據(jù)(注釋)。
先介紹第一種配置方式。需要指出的是,Spring2.X的beans名稱空間和Spring1.X有所不同,它采用了Schema而不是DTD(也可采用DTD方式,具體的請參考文檔)。還是引入毫無意義的日志切面,定義的切面類LogingAspect 如下:
public class LogingAspect {
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}
同時在配置文件中如下配置:
< bean id = " logAspectTarget " class = " hibernatesample.service.util.LogingAspect " >
</ bean >
< aop:config >
< aop:aspect id = " logAspect " ref = " logAspectTarget " >
< aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:after pointcut - ref = " businessService " method = " logMethod " />
</ aop:aspect >
</ aop:config >
對于上面的切面,切入點(diǎn)businessService是在配置文件中聲明的,其表達(dá)式采用了 AspectJ的語法,LogingAspect 類中l(wèi)ogMethod(JoinPoint jp)方法根據(jù)配置文件信息可知其是after通知,方法的JoinPoint參數(shù)不是必須的,它是來自于AspectJ的實(shí)用類,這里用它不過輸出一些和連接點(diǎn)有關(guān)的信息。當(dāng)然,在Spring2.X中,切入點(diǎn)和通知能更靈活的使用,我們可以如AspectJ一樣傳遞參數(shù)給通知。如果需要在Service中引入事務(wù)功能,需要如下配置事務(wù)通知:
< tx:advice id = " txAdvice " transaction - manager = " transactionManager " >
< tx:attributes >
< tx:method name = " get* " read - only = " true " />
< tx:method name = " find* " read - only = " true " />
< tx:method name = " * " />
</ tx:attributes >
</ tx:advice >
< aop:config >
< aop:pointcut id = " demoServiceMethods " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:advisor advice - ref = " txAdvice " pointcut - ref = " demoServiceMethods " />
< aop:aspect id = " logAspect " ref = " logAspectTarget " >
< aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " />
< aop:after pointcut - ref = " businessService " method = " logMethod " />
</ aop:aspect >
</ aop:config >
完成上面的工作相當(dāng)于完成了 Spring1.X 的 自動代理。 我們接下來需要定義的任何 Service Bean 都可以很純粹很純粹了:
< bean id ="accountService" class ="hibernatesample.service.impl.AccountServiceImpl" >
< property name ="accountDAO" ref ="accountDAO" ></ property >
</ bean >
第二種實(shí)現(xiàn) AOP 的方式和第一種相比,只是在 LogingAspect 中加入了注釋,而省去了配置文件中和 LogingAspect 相關(guān)的配置。重新編寫的 LogingAspect 如下:
@Aspect
public class LogingAspect {
@Pointcut( " execution(* hibernatesample.service.*.*(..)) " )
public void businessService(){}
@After( " businessService() " )
public void logMethod(JoinPoint jp){
System.err.println(jp.getTarget().getClass());
System.err.println(jp.getSignature().getName());
}
}
而簡化后的配置文件可以去除上面的如下和 logAspect 相關(guān)的配置信息:
< aop:aspect id ="logAspect" ref ="logAspectTarget" >
< aop:pointcut id ="businessService" expression ="execution(* hibernatesample.service.*.*(..))" />
< aop:after pointcut-ref ="businessService" method ="logMethod" />
</ aop:aspect >
< bean id ="logAspectTarget" class ="hibernatesample.service.util.LogingAspect" ></ bean >
還沒有完,為了使 Spring 應(yīng)用 LogingAspect 的注釋,需要在配置文件中添上
<aop:aspectj-autoproxy/>
如果覺得事務(wù)的配置沒有使用注釋更簡潔(我倒不會有這樣的想法,畢竟在配置文件中聲明的事務(wù)只是那么固定的幾段,除非作用于類上的事務(wù)邏輯上很復(fù)雜),也可以使用Spring提供的事務(wù)注釋作用于類文件上,這可是更細(xì)粒度的事務(wù)聲明了。
坦率的說,由于時間有限,該文寫的比較粗糙。對于Spring AOP有興趣并有疑問的朋友,可以參考Spring的文檔,它的文檔做的還是不錯的。

