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

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 河源市| 德保县| 仙居县| 民权县| 永州市| 盱眙县| 伽师县| 运城市| 巴中市| 香港| 泽州县| 沛县| 门源| 饶阳县| 淅川县| 张家口市| 英吉沙县| 延津县| 原平市| 忻城县| 广水市| 通城县| 逊克县| 广平县| 三河市| 桐梓县| 贡嘎县| 阳东县| 仪征市| 镇安县| 东至县| 治多县| 兴文县| 成武县| 白城市| 岑溪市| 县级市| 墨江| 夏津县| 武胜县| 赤水市|