<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),也就是常說的面向方面編程,它是作為面向對象編程的一種補充,專門用于處理系統中分布于各個模塊(不同方法)

    中的交叉關注點的問題,在 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)






















     




       [ 轉載出處:http://www.tkk7.com/fancydeepin ]

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

    主站蜘蛛池模板: 麻豆国产精品入口免费观看| 色片在线免费观看| 四虎永久免费地址在线观看| 中日韩亚洲人成无码网站| 亚洲一区二区免费视频| 亚洲人成网网址在线看| 成年女人毛片免费视频| 亚洲日韩精品无码专区加勒比☆ | 久久亚洲中文无码咪咪爱| 青青草免费在线视频| 亚洲熟女综合色一区二区三区| 成年轻人网站色免费看| 亚洲精品欧美综合四区| 国产福利免费观看| 国产日韩久久免费影院| 亚洲三级电影网址| 无码人妻精品中文字幕免费东京热| 亚洲国产精品综合一区在线| 女人毛片a级大学毛片免费| 国产精品亚洲а∨天堂2021| 国产亚洲一区二区三区在线不卡| 免费91最新地址永久入口| 亚洲国产成a人v在线| 日本一线a视频免费观看| h片在线观看免费| 久久丫精品国产亚洲av不卡| 色播精品免费小视频| 黄色三级三级免费看| 亚洲AV无码久久精品狠狠爱浪潮| 韩国免费一级成人毛片| 看一级毛片免费观看视频| 亚洲国产精品无码一线岛国| 97性无码区免费| 一道本在线免费视频| 亚洲首页在线观看| 国产无遮挡裸体免费视频| 免费国产成人18在线观看| 亚洲精品无码高潮喷水A片软| 久久亚洲国产欧洲精品一| 无码一区二区三区免费视频 | 亚洲资源在线视频|