1. 程式人生 > >spring中aop的註解實現方式簡單實例

spring中aop的註解實現方式簡單實例

xsd 說話 2017年 nco 執行 str throw tar pac

  上篇中我們講到spring的xml實現,這裏我們講講使用註解如何實現aop呢。前面已經講過aop的簡單理解了,這裏就不在贅述了。

註解方式實現aop我們主要分為如下幾個步驟(自己整理的,有更好的方法的話,[email protected]):

  1.在切面類(為切點服務的類)[email protected],聲明為一個切面類。

[email protected],目的是為了告訴切面,誰是它的服務對象。(此註釋修飾的方法的方法體為空,不需要寫功能比如 public void say(){};就可以了,方法名可以被候命的具體服務功能所以引用,它可以被理解為切點對象的一個代理對象方法)

  3.在對應的方法前用對應的通知類型註釋修飾,將對應的方法聲明稱一個切面功能,為了切點而服務

  4.在spring配置文件中開啟aop註釋自動代理。如:<aop:aspectj-autoproxy/>

這樣講可能還是很抽象,那麽,廢話不多說,我們代碼說話,代碼如下:

騎士類:(看過上一篇內容的就知道騎士是什麽東西了,嘿嘿嘿)

 1 package com.cjh.aop2;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * @author Caijh
 7  *
 8  * 2017年7月11日 下午3:53:19
9 */ 10 @Component("knight") 11 public class BraveKnight { 12 public void saying(){ 13 System.out.println("我是騎士..(切點方法)"); 14 } 15 }

切面類:(註釋主要在這裏體現)

 1 package com.cjh.aop2;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.After;
 5 import org.aspectj.lang.annotation.Around;
6 import org.aspectj.lang.annotation.Aspect; 7 import org.aspectj.lang.annotation.Before; 8 import org.aspectj.lang.annotation.Pointcut; 9 import org.springframework.stereotype.Component; 10 11 /** 12 * @author Caijh 13 * email:[email protected] 14 * 2017年7月12日 上午9:31:43 15 */ 16 /** 17 * 註解方式聲明aop 18 * [email protected]([email protected]("")註解註釋為一個bean對象,那麽就要在spring配置文件中開啟註解掃描,<context:component-scan base-package="com.cjh.aop2"/> 19 * 否則要在spring配置文件中聲明一個bean對象) 20 * 2.在切面需要實現相應方法的前面加上相應的註釋,也就是通知類型。 21 * 3.此處有環繞通知,環繞通知方法一定要有ProceedingJoinPoint類型的參數傳入,然後執行對應的proceed()方法,環繞才能實現。 22 */ 23 @Component("annotationTest") 24 @Aspect 25 public class AnnotationTest { 26 //定義切點 27 @Pointcut("execution(* *.saying(..))") 28 public void sayings(){} 29 /** 30 * 前置通知(註解中的sayings()方法,其實就是上面定義pointcut切點註解所修飾的方法名,那只是個代理對象,不需要寫具體方法, 31 * 相當於xml聲明切面的id名,如下,相當於id="embark",用於供其他通知類型引用) 32 * <aop:config> 33 <aop:aspect ref="mistrel"> 34 <!-- 定義切點 --> 35 <aop:pointcut expression="execution(* *.saying(..))" id="embark"/> 36 <!-- 聲明前置通知 (在切點方法被執行前調用) --> 37 <aop:before method="beforSay" pointcut-ref="embark"/> 38 <!-- 聲明後置通知 (在切點方法被執行後調用) --> 39 <aop:after method="afterSay" pointcut-ref="embark"/> 40 </aop:aspect> 41 </aop:config> 42 */ 43 @Before("sayings()") 44 public void sayHello(){ 45 System.out.println("註解類型前置通知"); 46 } 47 //後置通知 48 @After("sayings()") 49 public void sayGoodbey(){ 50 System.out.println("註解類型後置通知"); 51 } 52 //環繞通知。註意要有ProceedingJoinPoint參數傳入。 53 @Around("sayings()") 54 public void sayAround(ProceedingJoinPoint pjp) throws Throwable{ 55 System.out.println("註解類型環繞通知..環繞前"); 56 pjp.proceed();//執行方法 57 System.out.println("註解類型環繞通知..環繞後"); 58 } 59 }

spring配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 9     <!-- 開啟註解掃描 -->
10     <context:component-scan base-package="com.cjh.aop2"/>
11     <!-- 開啟aop註解方式,此步驟s不能少,這樣java類中的aop註解才會生效 -->
12     <aop:aspectj-autoproxy/>
13 </beans>

測試代碼:

 1 package com.cjh.aop2;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 /**
 7  * 
 8  * @author Caijh
 9  * email:[email protected]
10  * 2017年7月11日 下午6:27:06
11  */
12 public class Test {
13     public static void main(String[] args) {
14         ApplicationContext ac = new ClassPathXmlApplicationContext("com/cjh/aop2/beans.xml");
15         BraveKnight br = (BraveKnight) ac.getBean("knight");
16         br.saying();
17     }
18 }

運行結果:

註解類型環繞通知..環繞前
註解類型前置通知
我是騎士..(切點方法)
註解類型環繞通知..環繞後
註解類型後置通知

========================分割線===================================

  因為使用了註解方式,所以配置文件少了很多內容,只需要一句<context:component-scan base-package="com.cjh.aop2"/>聲明要掃描的包,[email protected]("knight")這個註釋,和<bean id="knight" class="com.cjh.aop2.BraveKnight"/>這個配置時一樣的意思,框架會自動識別並創建名為knight的BraveKnight對象。所以有了註釋,只需要開啟註釋掃描配置就好了,無需再做相同的bean配置。

  如果運行過程中出現Spring aop : error at ::0 can‘t find referenced pointcut sleepPonit的錯誤,那麽很可能是spring的包的版本問題,

  我用的是spring4的版本,然後還需要加aspectjrt-1.7.4.jar和aspectjweaver-1.7.4.jar兩個包,雲盤地址:鏈接:http://pan.baidu.com/s/1qXQurO4 密碼:nc4i

工程目錄如下:(打碼碼的類不用管,只是為了不為大家造成誤導,所以劃掉了)

技術分享

通知註解類型如下:

技術分享

spring中aop的註解實現方式簡單實例