和Spring1.X相比,Spring2.X使用AspectJ的語法來聲明AOP,這使得它更「標準」,更靈活了。仍是那句話,若是你不瞭解AspectJ而且打算使用Spring2.X的AspectJ式AOP,那就學學AspectJ吧,這方面的書仍是不少了。 Spring2.X下的切面有兩種實現方式,一種是以Java文件定義切面(其只是普通的Java類),而後在配置文件中聲明定義的切面;另外一種是在Java類中引入和AOP相關的元數據(註釋)。 先介紹第一種配置方式。須要指出的是,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> 對於上面的切面,切入點businessService是在配置文件中聲明的,其表達式採用了 AspectJ的語法,LogingAspect 類中logMethod(JoinPoint jp)方法根據配置文件信息可知其是after通知,方法的JoinPoint參數不是必須的,它是來自於AspectJ的實用類,這裏用它不過輸出一些 和鏈接點有關的信息。固然,在Spring2.X中,切入點和通知能更靈活的使用,咱們能夠如AspectJ同樣傳遞參數給通知。若是須要在 Service中引入事務功能,須要以下配置事務通知: <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> 完成上面的工做至關於完成了 Spring1.X 的 自動代理。 咱們接下來須要定義的任何 Service Bean 均可以很純粹很純粹了: <bean id ="accountService" class ="hibernatesample.service.impl.AccountServiceImpl"> <property name ="accountDAO" ref ="accountDAO"></ property> </ bean> 第二種實現 AOP 的方式和第一種相比,只是在 LogingAspect 中加入了註釋,而省去了配置文件中和 LogingAspect 相關的配置。從新編寫的 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 相關的配置信息: <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 應用 LogingAspect 的註釋,須要在配置文件中添上 <aop:aspectj-autoproxy/> 若是以爲事務的配置沒有使用註釋更簡潔(我倒不會有這樣的想法,畢竟在配置文件中聲明的事務只是那麼固定的幾段,除非做用於類上的事務邏輯上很複雜),也可使用Spring提供的事務註釋做用於類文件上,這但是更細粒度的事務聲明瞭。 --轉載至程式先鋒網站[url]www.javabiz.cn[/url]