AOP切面是一個非常不錯的特性,為我們帶來了一種新的編程方式,對代碼的無侵入性是它最大的特點。像上篇我們用到的Struts2攔截器就是AOP的一個典型運用。從Spring的低版本開始就能夠實現切面功能,但是非常麻煩,不過當Spring升級到2.0之后,這一情況就徹底改變了。運用JDK 5.0支持的注解特性,大大方便了我們的開發(fā)。在本篇中,大象將以AspectJ注解方式實現AOP的切面功能。
在這里我還是假設一下,你已經對Spring AOP有一個基本了解,至少知道AOP的基本概念,比如:切入點,通知,切入表達式,橫切邏輯等等內容。那么只需要在之前的基礎上做下小小的改變,就可以使用AspectJ實現日志的登錄登出功能。
增加日志表
記錄日志信息當然需要日志表了,我們在數據庫中增加一個log表。
增加實體類
增加Log實體類,字段名與屬性名一致,這樣就可以不用加Column注解了。另外沒有其它的關聯關系,這個類很干凈,是一個純POJO類。具體請看源碼,這里就不貼出來了。
增加切面類
這就是本篇的關鍵所在了,定義切面類。在common包下面再增加一個aop包,創(chuàng)建LogAspect類。
在LogAspect類之上標明@Aspect注解,指定此類為一個切面類。這樣的實現方式是不是很簡單?然后定義切入點與通知類型以及切入實現(一般叫做橫切增強,其實就是切入之后想實現的功能)。這里我實現了兩個切入方法,一個是登錄,當執(zhí)行完登錄操作,還沒有轉向到結果頁面時執(zhí)行;另一個是登出,在執(zhí)行登出之前調用橫切邏輯。最后一個是共用的保存日志方法,這里只是簡單的說明日志記錄如何實現,可以對日志表進行擴充,比如增加用戶ID、IP地址、模塊ID等等信息。
@Before和@After都是通知類型,前者是在連接點之前執(zhí)行,后者則是在連接點之后執(zhí)行。
修改struts.xml
增加一行配置<constant name="struts.objectFactory.spring.autoWire.alwaysRespect"
value="true" />,作用是確保Spring的自動裝配策略總是被考慮。默認為false,如果不將它改為true,則在使用CGLib代理Action類后,使用@Autowired注入的service類將會為null,那么這些目標方法中與數據庫交互的邏輯都不能執(zhí)行,所以一定要將它改為true。
修改applicationContext.xml
添加<aop:aspectj-autoproxy proxy-target-class="true" />聲明,為Spring容器中那些匹配@AspectJ切面的Bean創(chuàng)建代理,其中的proxy-target-class="true" 表示使用CGLib動態(tài)代理技術織入增強,不過只聲明還不行,還得織入,把編寫好的切面類完整路徑添加到配置文件中,這樣才能發(fā)揮切面的功能。
到這里,所有工作都已經完成,啟動服務器,來試一下,看看登入登出后,log表中是否會有記錄?呵呵,當然會有了,要是沒有大象也不敢寫出來找罵了。通過這個實例,我們可以看到,運用AOP的思想可以進行無侵入式的開發(fā),這符合當前非常強調的松耦合性,對以后的維護來講也相對會簡單一些。
posted on 2011-05-13 23:07
菠蘿大象 閱讀(5976)
評論(2) 編輯 收藏 所屬分類:
Struts2