<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    午后星期午

    Spring AOP + AspectJ framework

    AOP(Aspect Orient Programming),也就是常說的面向方面編程,它是作為面向?qū)ο缶幊痰囊环N補(bǔ)充,專門用于處理系統(tǒng)中分布于各個(gè)模塊(不同方法)

    中的交叉關(guān)注點(diǎn)的問題,在 Java EE 應(yīng)用中,常常通過 AOP 來處理一些具有橫切性質(zhì)的系統(tǒng)級服務(wù),如事務(wù)管理、安全檢查、緩存、對象池管理等。

    簡單點(diǎn)來說,它就是一個(gè)攔截器可以攔截一些進(jìn)程,例如,當(dāng)某個(gè)方法執(zhí)行時(shí),Spring AOP 可以攔截該執(zhí)行的方法,并允許在方法執(zhí)行之前或之后添加額外的功能,

    以上如若解釋的不好,勿噴 -_- ||

    AspectJ 是一個(gè)基于 Java 語言的 AOP 框架,提供了強(qiáng)大的 AOP 功能,Spring 從 2.0 起,對 AspectJ 功能都提供了支持 .

    幾個(gè)常用的 AspectJ 注解 : 

        @Before   在方法執(zhí)行前被執(zhí)行

        @After     在方法執(zhí)行后被執(zhí)行

        @AfterReturning     在方法執(zhí)行后被執(zhí)行,并同時(shí)攔截方法返回的結(jié)果

        @AfterThrowing      在方法拋出異常時(shí)候被執(zhí)行,若方法不拋出異常,則不會被執(zhí)行

        @Around   這個(gè),不知道要怎么解釋了,比較不好解釋,就像你攔截了一個(gè)方法,并在適當(dāng)?shù)臅r(shí)候給予放行,放行前后可以做額外的處理,下面看示例就很容易明白了

    環(huán)境 :

     
    eclipse  3.6
    maven  3.0.4
    spring   3.0.5
    aspectj 1.6.11
     


    pom.xml 清單 :

     
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation
    ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      
    <modelVersion>4.0.0</modelVersion>
      
    <groupId>com.fancy</groupId>
      
    <artifactId>spring-aop</artifactId>
      
    <packaging>war</packaging>
      
    <version>1.0</version>
      
    <name>spring-aop Maven Webapp</name>
      
    <url>http://maven.apache.org</url>
      
      
    <properties>
        
    <spring.version>3.0.5.RELEASE</spring.version>
        
    <aspectj.version>1.6.11</aspectj.version>
      
    </properties>
      
      
    <dependencies>
        
        
    <dependency>
          
    <groupId>org.springframework</groupId>
          
    <artifactId>spring-core</artifactId>
          
    <version>${spring.version}</version>
        
    </dependency>
     
        
    <dependency>
          
    <groupId>org.springframework</groupId>
          
    <artifactId>spring-context</artifactId>
          
    <version>${spring.version}</version>
        
    </dependency>
     
        
    <!-- Spring AOP + AspectJ -->
        
    <dependency>
          
    <groupId>org.springframework</groupId>
          
    <artifactId>spring-aop</artifactId>
          
    <version>${spring.version}</version>
        
    </dependency>
     
        
    <dependency>
          
    <groupId>org.aspectj</groupId>
          
    <artifactId>aspectjrt</artifactId>
          
    <version>${aspectj.version}</version>
        
    </dependency>
     
        
    <dependency>
          
    <groupId>org.aspectj</groupId>
          
    <artifactId>aspectjweaver</artifactId>
          
    <version>${aspectj.version}</version>
        
    </dependency>
        
        
    <dependency>
          
    <groupId>junit</groupId>
          
    <artifactId>junit</artifactId>
          
    <version>4.7</version>
          
    <scope>test</scope>
        
    </dependency>
        
      
    </dependencies>
      
      
    <build>
        
    <finalName>spring-aop</finalName>
      
    </build>
      
    </project>
     


    applicationContext.xml 清單 :

     
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:p
    ="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:aop
    ="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation
    ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
    >
        
      
    <!-- 開啟注解 -->
      
    <context:annotation-config/>
      
    <!-- 自動掃描 -->
      
    <context:component-scan base-package="com.fancy"/>
      
    <!-- 啟動 AspectJ 支持 -->
      
    <aop:aspectj-autoproxy />
        
    </beans>
     


    還是來編寫 HelloWorld :

    1 . 編寫 HelloWorld 接口

     
    package com.fancy.service;

    public interface HelloWorld {

        
    public void sayHi();
        
        
    public void sayHiAround(String username);
        
        
    public void sayHiThrowException() throws Exception;
        
        
    public String  sayHiReturnValue();
        
    }
     


    2 . 編寫 HelloWorld 接口的實(shí)現(xiàn),并將其注解成 spring 的一個(gè)組件

     
    package com.fancy.service.impl;

    import com.fancy.service.HelloWorld;
    import org.springframework.stereotype.Component;

    @Component
    public class HelloWorldImpl implements HelloWorld {

        
    public void sayHi() {
            
            System.out.println(
    "sayHi ---->> Hi fancy !");
        }

        
    public void sayHiAround(String username) {
            
            System.out.println(
    "sayHiAround ---->> Hi " + username + " !");
        }

        
    public void sayHiThrowException() throws Exception {
            
            System.out.println(
    "sayHiThrowException ---->> Hi fancy !");
            
    throw new Exception("Throw an exception here !!!!");
        }

        
    public String sayHiReturnValue() {
            
            System.out.println(
    "sayHiReturnValue ---->> Hi fancy !");
            
    return "fancy";
        }
        
    }
     


    3 . 編寫方面代碼 :

    AspectJ @Before 示例

     
    package com.fancy.aspect;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    public class MyAspect {

        @Before(
    "execution (* com.fancy.service.HelloWorld.sayHi(..))")
        
    public void logBefore(JoinPoint   joinPoint){
            
            System.out.println(
    "logBefore() Method Invoke!");
            System.out.println(
    "Hijack Method Name : " + joinPoint.getSignature().getName());
        }
        
    }
     

    其中,@Before("execution (* com.fancy.service.HelloWorld.sayHi(..))") 中的 execution (* com.fancy.service.HelloWorld.sayHi(..)) 是切入點(diǎn)表達(dá)式,

    更多的幫助信息可以查看 spring 的幫助文檔,spring 3.0.5 的幫助文檔中是在 第 7  章的 7.2.3.4 小節(jié),因?yàn)槲臋n上說的也不是太清楚,在這里我也不好說話,

    其中的 execution 是用于匹配方法執(zhí)行的連接點(diǎn),那個(gè) * 號所占的位不知道是不是代表方法的訪問權(quán)限,文檔上沒說,網(wǎng)上也沒找到相關(guān)解釋,哪位知道的望告知啊~~

    接下來的 com.fancy.service.HelloWorld.sayHi 就很明顯了,就是切入點(diǎn)方法名,再接下來的是 (..),(..) 代表匹配任意數(shù)量的參數(shù),可以是 0 個(gè)也可以是多個(gè) ;

    如果你確定這個(gè)方法不需要參數(shù),可以直接使用 (),還可以使用 (*) 來匹配一個(gè)任意類型的參數(shù),還可以使用 (* , String),這樣代表匹配兩個(gè)參數(shù),第二個(gè)參數(shù)必須是

    String 類型的參數(shù),這些在 spring 幫助文檔的 7.2.3.4 小節(jié)都有說到,在這里就不多說了,可以自己去看,英文的看起來更帶勁 *_*

    再接下來的是 JoinPoint 接口,org.aspectj.lang.JoinPoint 接口表示的是目標(biāo)類連接點(diǎn)對象,這個(gè)我也找不到相關(guān)的 API,只能手工整理一下了 :

    JoinPoint     API 

         java.lang.Object                getThis() :獲取代理對象本身;

         java.lang.Object           getTarget() :獲取連接點(diǎn)所在的目標(biāo)對象; 

        Signature                   getSignature() :獲取連接點(diǎn)的方法簽名對象; 

        java.lang.Object[]             getArgs():獲取連接點(diǎn)方法運(yùn)行時(shí)的入?yún)⒘斜恚?nbsp;
                 

    Junit 測試

     
    package junit.test;

    import org.junit.Test;
    import org.junit.BeforeClass;
    import com.fancy.service.HelloWorld;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class TestApp {
        
        
    private static ApplicationContext context = null;
        
        @BeforeClass
        
    public static void setUpBeforeClass() throws Exception {

            context 
    = new ClassPathXmlApplicationContext("applicationContext.xml");
        }
        
        @Test
        
    public void testMethod() throws Exception{
            
            HelloWorld helloworld 
    = (HelloWorld)context.getBean("helloWorldImpl");
            helloworld.sayHi();
        }

    }
     

    后臺輸出 :

     
    logBefore() Method Invoke
    !
    Hijack Method Name : sayHi
    sayHi 
    ---->> Hi fancy !
     


    AspectJ @After 示例

     
    package com.fancy.aspect;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    public class MyAspect {


        @After(
    "execution (* com.fancy.service.HelloWorld.sayHi(..))")
        
    public void logAfter(JoinPoint   joinPoint){
            
            System.out.println(
    "logAfter() Method Invoke!");
            System.out.println(
    "Hijack Method Name : " + joinPoint.getSignature().getName());
        }
        
    }
     

    Junit 測試

     
    @Test
        
    public void testMethod() throws Exception{
            
            HelloWorld helloworld 
    = (HelloWorld)context.getBean("helloWorldImpl");
            helloworld.sayHi();
        }
     

    后臺輸出 :

     
    sayHi 
    ---->> Hi fancy !
    logAfter() Method Invoke
    !
    Hijack Method Name : sayHi
     


    AspectJ @AfterReturning 示例

     
    package com.fancy.aspect;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    public class MyAspect {


        @AfterReturning(pointcut 
    = "execution (* com.fancy.service.HelloWorld.sayHiReturnValue(..))", returning = "returnValue")
        
    public void logAfterReturning(JoinPoint   joinPoint, Object/*String*/ returnValue){
            
            System.out.println(
    "logAfterReturning() Method Invoke!");
            System.out.println(
    "Hijack Method Name : " + joinPoint.getSignature().getName());
            System.out.println(
    "The Return Value Is : " + returnValue);
        }
        
    }
     

    Junit 測試

     
    @Test
        
    public void testMethod() throws Exception{
            
            HelloWorld helloworld 
    = (HelloWorld)context.getBean("helloWorldImpl");
            helloworld.sayHiReturnValue();
        }
     

    后臺輸出 :

     
    sayHiReturnValue 
    ---->> Hi fancy !
    logAfterReturning() Method Invoke
    !
    Hijack Method Name : sayHiReturnValue
    The Return Value Is : fancy
     


    AspectJ @AfterThrowing 示例

     
    package com.fancy.aspect;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    public class MyAspect {


        @AfterThrowing(pointcut 
    = "execution (* com.fancy.service.HelloWorld.sayHiThrowException(..))", throwing = "error")
        
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error){
            
            System.out.println(
    "logAfterThrowing() Method Invoke!");
            System.out.println(
    "Hijack Method Name : " + joinPoint.getSignature().getName());
            System.out.println(
    "Exception Message  :" + error);
        }
        
    }
     

    Junit 測試

     
    @Test
        
    public void testMethod() throws Exception{
            
            HelloWorld helloworld 
    = (HelloWorld)context.getBean("helloWorldImpl");
            helloworld.sayHiThrowException();
        }
     

    后臺輸出 :

     
    sayHiThrowException 
    ---->> Hi fancy !
    logAfterThrowing() Method Invoke
    !
    Hijack Method Name : sayHiThrowException
    Exception Message  :java.lang.Exception: Throw an exception here 
    !!!!
     

    若將 HelloWorldImpl 類中 sayHiThrowException 方法的異常拋出注釋掉,

     
    public void sayHiThrowException() throws Exception {
            
            System.out.println(
    "sayHiThrowException ---->> Hi fancy !");
            
    //throw new Exception("Throw an exception here !!!!");
        }
     

    其余不變,再次執(zhí)行 Junit 測試,后臺輸出 :

     
    sayHiThrowException 
    ---->> Hi fancy !
     

    這就說明,當(dāng)該方法能夠運(yùn)行正常的時(shí)候,沒有拋出異常,則,logAfterThrowing 不會被執(zhí)行 .


    AspectJ @Around 示例

     
    package com.fancy.aspect;

    import java.util.Arrays;

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;

    @Aspect
    @Component
    public class MyAspect {


        @Around(
    "execution (* com.fancy.service.HelloWorld.sayHiAround(..))")
        
    public void logAround(ProceedingJoinPoint   joinPoint) throws Throwable {
            
            System.out.println(
    "logAround() Method Invoke!");
            System.out.println(
    "Hijack Method Name  : " + joinPoint.getSignature().getName());
            System.out.println(
    "Hijack Arguments Is : " + Arrays.toString(joinPoint.getArgs()));
            System.out.println(
    "Around before : can do something here !");
            joinPoint.proceed(); 
    //放行
            System.out.println("Around after  : can do something here !");
        }
        
    }
     

    Junit 測試

     
    @Test
        
    public void testMethod() throws Exception{
            
            HelloWorld helloworld 
    = (HelloWorld)context.getBean("helloWorldImpl");
            helloworld.sayHiAround(
    "fancy");
        }
     

    后臺輸出 :

     
    logAround() Method Invoke
    !
    Hijack Method Name  : sayHiAround
    Hijack Arguments Is : [fancy]
    Around before : can 
    do something here !
    sayHiAround 
    ---->> Hi fancy !
    Around after  : can 
    do something here !
     

    其中,需要提一下 ProceedingJoinPoint 接口 :

    ProceedingJoinPoint 繼承于 JoinPoint,是其子接口,它新增了兩個(gè)用于執(zhí)行連接點(diǎn)方法的方法: 

         java.lang.Object proceed() throws java.lang.Throwable:通過反射執(zhí)行目標(biāo)對象的連接點(diǎn)處的方法; 

         java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執(zhí)行目標(biāo)對象連接點(diǎn)處的方法,不過使用新的入?yún)⑻鎿Q原來的入?yún)ⅰ?br />

    最后附上 spring 3.0.5 幫助文檔中的一些信息 :

    Some examples of common pointcut expressions are given below.

    • the execution of any public method:

      execution(public * *(..))
    • the execution of any method with a name beginning with "set":

      execution(* set*(..))
    • the execution of any method defined by the AccountService interface:

      execution(* com.xyz.service.AccountService.*(..))
    • the execution of any method defined in the service package:

      execution(* com.xyz.service.*.*(..))
    • the execution of any method defined in the service package or a sub-package:

      execution(* com.xyz.service..*.*(..))
    • any join point (method execution only in Spring AOP) within the service package:

      within(com.xyz.service.*)
    • any join point (method execution only in Spring AOP) within the service package or a sub-package:

      within(com.xyz.service..*)
    • any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface:

      this(com.xyz.service.AccountService)

      'this' is more commonly used in a binding form :- see the following section on advice for how to make the proxy object available in the advice body.

    • any join point (method execution only in Spring AOP) where the target object implements the AccountService interface:

      target(com.xyz.service.AccountService)

      'target' is more commonly used in a binding form :- see the following section on advice for how to make the target object available in the advice body.

    • any join point (method execution only in Spring AOP) which takes a single parameter, and where the argument passed at runtime is Serializable:

      args(java.io.Serializable)

      'args' is more commonly used in a binding form :- see the following section on advice for how to make the method arguments available in the advice body.

      Note that the pointcut given in this example is different to execution(* *(java.io.Serializable)): the args version matches if the argument passed at runtime is Serializable, the execution version matches if the method signature declares a single parameter of type Serializable.

    • any join point (method execution only in Spring AOP) where the target object has an @Transactional annotation:

      @target(org.springframework.transaction.annotation.Transactional)

      '@target' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    • any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:

      @within(org.springframework.transaction.annotation.Transactional)

      '@within' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    • any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation:

      @annotation(org.springframework.transaction.annotation.Transactional)

      '@annotation' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    • any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the@Classified annotation:

      @args(com.xyz.security.Classified)

      '@args' can also be used in a binding form :- see the following section on advice for how to make the annotation object(s) available in the advice body.

    • any join point (method execution only in Spring AOP) on a Spring bean named 'tradeService':

      bean(tradeService)
    • any join point (method execution only in Spring AOP) on Spring beans having names that match the wildcard expression '*Service':

      bean(*Service)






















     




       [ 轉(zhuǎn)載出處:http://www.tkk7.com/fancydeepin ]

    posted on 2013-12-31 13:43 午后星期午 閱讀(169) 評論(0)  編輯  收藏 所屬分類: JavaEE

    主站蜘蛛池模板: 国产真实伦在线视频免费观看| 亚洲成在人线电影天堂色| 99蜜桃在线观看免费视频网站| 日韩少妇内射免费播放| 亚洲日韩在线中文字幕综合| 亚洲av永久无码精品秋霞电影影院 | 亚洲综合激情另类小说区| 日本高清免费不卡视频| 亚洲愉拍99热成人精品热久久 | a级毛片毛片免费观看永久| gogo免费在线观看| 精品国产呦系列在线观看免费| 激情综合亚洲色婷婷五月 | 亚洲性日韩精品国产一区二区| 亚洲精品456播放| 亚洲国产日韩成人综合天堂| 嫖丰满老熟妇AAAA片免费看| 免费观看美女用震蛋喷水的视频 | 国产精品九九久久免费视频| 亚洲综合久久一本伊伊区| 亚洲男同帅GAY片在线观看| 日韩一级免费视频| jjzz亚洲亚洲女人| 国产亚洲精品看片在线观看| 久久亚洲国产精品一区二区| 亚洲精品福利网泷泽萝拉| 亚洲a级片在线观看| 亚洲爆乳无码专区www| 免费a级毛片无码a∨性按摩| 黄+色+性+人免费| 国产成人A在线观看视频免费| 国产福利免费在线观看| 国产亚洲情侣一区二区无码AV| 麻豆国产入口在线观看免费| 国产区卡一卡二卡三乱码免费| 亚洲毛片av日韩av无码| 日韩免费观看的一级毛片| 噼里啪啦免费观看高清动漫4 | 99免费在线视频| h在线观看视频免费网站| 成全高清视频免费观看|