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

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

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

    隨筆-126  評論-247  文章-5  trackbacks-0

    AOP(Aspect Orient Programming),也就是常說的面向方面編程,它是作為面向對象編程的一種補充,專門用于處理系統中分布于各個模塊(不同方法)

    中的交叉關注點的問題,在 Java EE 應用中,常常通過 AOP 來處理一些具有橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等。

    簡單點來說,它就是一個攔截器可以攔截一些進程,例如,當某個方法執行時,Spring AOP 可以攔截該執行的方法,并允許在方法執行之前或之后添加額外的功能,

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

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

    幾個常用的 AspectJ 注解 : 

        @Before   在方法執行前被執行

        @After     在方法執行后被執行

        @AfterReturning     在方法執行后被執行,并同時攔截方法返回的結果

        @AfterThrowing      在方法拋出異常時候被執行,若方法不拋出異常,則不會被執行

        @Around   這個,不知道要怎么解釋了,比較不好解釋,就像你攔截了一個方法,并在適當的時候給予放行,放行前后可以做額外的處理,下面看示例就很容易明白了

    環境 :

     
    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 接口的實現,并將其注解成 spring 的一個組件

     
    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(..)) 是切入點表達式,

    更多的幫助信息可以查看 spring 的幫助文檔,spring 3.0.5 的幫助文檔中是在 第 7  章的 7.2.3.4 小節,因為文檔上說的也不是太清楚,在這里我也不好說話,

    其中的 execution 是用于匹配方法執行的連接點,那個 * 號所占的位不知道是不是代表方法的訪問權限,文檔上沒說,網上也沒找到相關解釋,哪位知道的望告知啊~~

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

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

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

    再接下來的是 JoinPoint 接口,org.aspectj.lang.JoinPoint 接口表示的是目標類連接點對象,這個我也找不到相關的 API,只能手工整理一下了 :

    JoinPoint     API 

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

         java.lang.Object           getTarget() :獲取連接點所在的目標對象; 

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

        java.lang.Object[]             getArgs():獲取連接點方法運行時的入參列表; 
                 

    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 !!!!");
        }
     

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

     
    sayHiThrowException 
    ---->> Hi fancy !
     

    這就說明,當該方法能夠運行正常的時候,沒有拋出異常,則,logAfterThrowing 不會被執行 .


    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,是其子接口,它新增了兩個用于執行連接點方法的方法: 

         java.lang.Object proceed() throws java.lang.Throwable:通過反射執行目標對象的連接點處的方法; 

         java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執行目標對象連接點處的方法,不過使用新的入參替換原來的入參。


    最后附上 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)






















     



      
    posted on 2012-10-05 00:31 fancydeepin 閱讀(4849) 評論(1)  編輯  收藏

    評論:
    # re: Spring AOP + AspectJ framework[未登錄] 2013-08-12 20:57 | tiger
    前面的那個*號是表示訪求的返回類型  回復  更多評論
      

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲精品二区国产综合野狼| 久久亚洲国产成人精品性色| 中文字幕在线免费观看视频| 亚洲AV无码不卡在线播放| 亚洲免费综合色在线视频| 国产精品免费久久久久影院| 亚洲精品免费在线| 亚洲精品无码成人片在线观看 | 亚洲日韩小电影在线观看| h视频在线观看免费网站| 免费无遮挡无遮羞在线看| 精品日韩亚洲AV无码一区二区三区 | 免费人成视频x8x8入口| 人妻丰满熟妇无码区免费 | 日韩电影免费在线观看| 亚洲国产精品无码中文lv| 亚洲日本va午夜中文字幕一区| 日本媚薬痉挛在线观看免费| 无人在线观看免费高清| 美女视频黄视大全视频免费的| 久久亚洲精品国产精品| 久久亚洲国产精品五月天婷| 女人18特级一级毛片免费视频| 久久国产免费观看精品| 黄色网址免费在线| 亚洲va久久久久| 亚洲福利在线视频| 亚洲综合色在线观看亚洲| 国产美女无遮挡免费视频| 国产四虎免费精品视频| 成全动漫视频在线观看免费高清版下载| 亚洲JLZZJLZZ少妇| 亚洲中文字幕无码一去台湾| 亚洲精品免费观看| 亚洲一区二区三区自拍公司| 免费看小12萝裸体视频国产| 国拍在线精品视频免费观看| 午夜免费福利小电影| a级毛片免费播放| 国产精品免费一区二区三区| 免费国产污网站在线观看不要卡|