@AspectJアノテーションを使用したスプリングアスペクトの3つの構成

定義
はAspectJと同じですが、Spring AOPは、新しいAOPプロキシクラスを生成するターゲットクラスも拡張する必要があります。AspectJとは異なり、Spring AOPはJavaソースコードをコンパイルするために特別なコマンドを使用する必要はなく、ランタイムを使用します。 AOPプロキシを生成するために、メモリ内に動的かつ一時的に「プロキシクラス」を生成します。

Springでは、アスペクト(Aspect)、ポイントカット(Pointcut)、拡張処理(Advice)を定義するためにAspectJアノテーションを使用でき、Springフレームワークはこれらのアノテーションに基づいてAOPプロキシを認識して生成できます。
簡単に言えば、Springは実行時に動的プロキシ生成を使用してターゲットオブジェクトを拡張するため、コンパイルを追加する必要も、AspectJウィーバーのサポートも必要ありません。AspectJはコンパイル時の拡張を使用するため、AspectJはTocompileを使用する必要があります。独自のコンパイラを使用したJavaファイルには、ウィーバーも必要です。一般的な実行クラスの

package com.samter.common; 
/** 
 * 猴子 
 * @author Administrator 
 */  
public class Monkey {
    
            
    public void stealPeaches(String name){
    
      
        System.out.println("【猴子】"+name+"正在偷桃...");  
    }  
}

ガーディアンクラス(アスペクトとして宣言):

package com.samter.aspect;  
import org.aspectj.lang.annotation.AfterReturning;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.aspectj.lang.annotation.Pointcut;  
  
/** 
 * 桃园守护者 
 * @author Administrator 
 */  
@Aspect  
public class Guardian {
    
      
      
    @Pointcut("execution(* com.samter.common.Monkey.stealPeaches(..))")  
    public void foundMonkey(){
    
    }  
  
    @Before(value="foundMonkey()")  
    public void foundBefore(){
    
      
        System.out.println("【守护者】发现猴子正在进入果园...");  
    }  
      
    @AfterReturning("foundMonkey() && args(name,..)")  
    public void foundAfter(String name){
    
      
        System.out.println("【守护者】抓住了猴子,守护者审问出了猴子的名字叫“"+name+"”...");  
    }  
      
}

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:aop="http://www.springframework.org/schema/aop"  
       xsi:schemaLocation="  
       http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
       http://www.springframework.org/schema/aop  
       http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"  
>  
  
    <!-- 定义Aspect -->  
    <bean id="guardian" class="com.samter.aspect.Guardian" />  
  
    <!-- 定义Common -->  
    <bean id="monkey" class="com.samter.common.Monkey" />  
  
    <!-- 启动AspectJ支持 -->  
    <aop:aspectj-autoproxy />  
</beans>

テストクラス

package com.samter.common;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Main {
    
      
    public static void main(String[] args) {
    
      
        ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");  
        Monkey monkey = (Monkey) context.getBean("monkey");  
        try {
    
      
            monkey.stealPeaches("孙大圣的大徒弟");  
        }  
        catch(Exception e) {
    
    }  
    }    
}

コンソール出力:

【守护者】发现猴子正在进入果园...  
【猴子】孙大圣的大徒弟正在偷桃...  
【守护者】抓住了猴子,守护者审问出了猴子的名字叫“孙大圣的大徒弟”... 

解説:

  1写了一个猴子正在偷桃的方法。 
  2写了一个标志为@Aspect的类,它是守护者。它会在猴子偷桃之前发现猴子,并在猴子偷桃之后抓住猴子。 
  原理:

        A、@Aspect的声明表示这是一个切面类。 
        B、@Pointcut使用这个方法可以将com.samter.common.Monkey.stealPeaches(..)方法声明为poincut即切入点。作用,在stealPeaches方法被调用的时候执行2的foundMonkey方法。其中execution是匹配方法执行的切入点,也就是spring最常用的切入点定义方式。 
        C、@Before(value="foundMonkey()"):@Before声明为在切入点方法执行之前执行,而后面没有直接声明切入点,而是value="foundMonkey()",是因为如果@afterReturning等都有所改动的时候都必须全部改动,所以统一用Pointcut的foundMonkey代替,这样子有改动的时候仅需改动一个地方。其他@AfterReturning类同。 
  3是xml配置文件,里面有具体的注释。 

特記事項:Guardianクラスの@Pointcut( "execution(* com.samter.common.Monkey.stealPeaches(...))")、stealPeachesにパラメーターがある場合、...はすべてのパラメーターを意味します。@ AfterReturning( "foundMonkey ()&& args(name、…)”)&& args(name、…)は、エントリポイントメソッドstealPeachesのパラメータを取得できます。

概要:これは簡単な例ですが、アプリケーションに拡張することは難しくありません。ログインシステムを作成するときは、システムに正常にログインしたユーザー、間違ったパスワードでシステムにログインしたユーザーを記録することをお勧めします。 、など。このようにすると、アスペクトがより適切になります。つまり、トランザクションロジックがログ、セキュリティチェック、トランザクション管理などの一般的なコンテンツを含むように設計されている場合、アスペクトは、関連コードまたは関連コードを持つトランザクションロジッククラス。引用ははるかに優れています。

@AspectJのAOP関数を構成するには、次の3つの方法があります。1。Spring
のXMLスキーマ構成方法を使用する:
2。@ AspectJを開始する(現時点では、関連するAOP構成はスキーマに必要ありません)
3。@ EnableAspectJAutoProxy(@Configuration注釈)spring 3.バージョン1以降では、
xml構成ファイルを使用せずに、@ Configurationを使用してSpringBeanをアセンブルし@ EnableAspectJAutoProxyを使用してSpringAOP関数を開始します。

@Aspectで

package com.dxz.aop.demo6;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;

// 定义一个方面
@Aspect
@Configuration
public class AfterReturningAdviceTest {
    
    
    // 匹配 com.dxz.aop.demo6 包下所有类的下的所有方法的执行作为切入点
    @AfterReturning(returning = "rvt", pointcut = "execution(* com.dxz.aop.demo6.*.*(..))")
    public void log(Object rvt) {
    
    
        System.out.println("AfterReturningAdviceTest==获取目标方法返回值 :" + rvt);
    }
}

春の構成クラス

package com.dxz.aop.demo6;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
@Import({
    
    AfterReturningAdviceTest.class})/*@Aspect可以生效,相当于Configuration类作用,都是配置类*/  
public class AppConfig {
    
    

    @Bean(name = "chinese")
    public Chinese chinese() {
    
    
        return new Chinese();
    }
}

クラスを開始

package com.dxz.aop.demo6;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test6 {
    
    

    public static void main(String[] args) {
    
    
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Person outPut = (Person) context.getBean("chinese");
        outPut.sayHello("duan");
    }
}

結果

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@c4437c4: startup date [Tue Dec 26 17:03:32 CST 2017]; root of context hierarchy
AfterReturningAdviceTest==获取目标方法返回值 :com.dxz.aop.demo6.Chinese@72967906
duan Hello , Spring AOP
AfterReturningAdviceTest==获取目标方法返回值 :duan Hello , Spring AOP
 

3つ、注釈

2アノテーション
2.1@Aspect

この関数は、現在のクラスをコンテナーが読み取るアスペクトとして識別することです。

2.2 @Before
は、BeforeAdviceの機能と同等の事前拡張メソッドを識別します。同様の機能があります。

2.3 @AfterReturning

メソッドが正常に終了したときに実行される、AfterReturningAdviceと同等のポストエンハンスメント

2.4 @AfterThrowing

ThrowsAdviceと同等の例外スロー機能拡張

2.5 @After

例外をスローするか正常に終了するかにかかわらず、最終的な拡張が実行されます

2.6 @Around

MethodInterceptorと同等のサラウンドエンハンスメント

2.7 @DeclareParents

IntroductionInterceptorと同等のIntroductionEnhancement

3実行ポイントカット機能

実行関数は、メソッド実行の接続ポイントを照合するために使用されます。構文は次のとおりです。

実行(メソッド修飾子(オプション)戻り値の型メソッド名パラメーター例外モード(オプション))

パラメータ部分ではワイルドカード文字を使用できます。

  • 任意の文字に一致しますが、要素は1つだけです

…任意の文字に一致し、任意の数の要素に一致できます。クラスを表す場合は、*と組み合わせて使用​​する必要があります。

  • クラス名の後に続く必要があります。たとえば、Horseman +は、クラス自体と、指定されたクラスを継承または拡張するすべてのクラスを意味します。

*例のChop(...)は次のように解釈されます。

メソッド修飾子なし

戻り値の型*は任意の数の文字に一致し、戻り値の型が無制限であることを示します

メソッド名chopは、名前chopに一致するメソッドを示します

パラメータ(...)は、任意の数とタイプの入力パラメータに一致することを意味します

無制限の例外モード

その他の例:

void chop(String、int)

ターゲットクラスの任意の修飾子メソッドに一致し、void、メソッド名chop、メソッドを文字列とint型パラメーターで返します

public void chop(*)

ターゲットクラスのパブリックモディフィケーションを一致させ、void、メソッド名chop、メソッドを任意のタイプのパラメーターと一致させます

public String o(…)

ターゲットクラスのパブリックモディフィケーションと一致し、文字列タイプを返し、メソッド名をo文字で、任意のタイプの任意の数のパラメーターを使用します

public void o(String、…)

ターゲットクラスのパブリックモディフィケーションに一致し、voidを返し、メソッド名をo文字で、任意のタイプのパラメーターをいくつでも使用できますが、最初のパラメーターには文字列タイプのメソッドが必要です。

クラスを指定することもできます。

public void examples.chap03.Horseman。*(…)

ホースマンの公開変更を一致させ、void、無制限のメソッド名、メソッドを任意のタイプの任意の数のパラメーターと一致させます

public voidexamples.chap03。おとこ。(…)

パブリック変更を照合し、void、無制限のメソッド名、メソッドを、manで終わるクラス内の任意のタイプの任意の数のパラメーターと一致させます

パッケージを指定します。

public void examples.chap03。*。chop(…)

examples.chap03パッケージのすべてのクラスで、パブリック変更、return void、メソッド名chop、およびメソッドを任意のタイプの任意の数のパラメーターと一致させます。

public voidexamples…*。chop(…)

public modify、return void、method name chop、methodを、examples.packageおよびすべてのサブパッケージのクラス内の任意のタイプの任意の数のパラメーターと一致させます。
これらの式を使用して、StorageAdvisorのコードを置き換え、効果を観察できます。

4その他のポイントカット関数
execution()に加えて、Springは他の多くの関数もサポートしています。名前と簡単な紹介は、必要に応じてより詳細なクエリを容易にするためにここにリストされています。

4.1 @annotation()

指定されたアノテーションでマークされたターゲットクラスメソッドを示します

たとえば、@ Annotation(org.springframework.transaction.annotation.Transactional)は、@ Transactionalを使用するメソッドを意味します

4.2 args()

ターゲットクラスメソッドのパラメータタイプでカットポイントを指定します

たとえば、args(String)は、Stringパラメータが1つしかないメソッドを意味します

4.3 @args()

ターゲットクラスパラメータのオブジェクトタイプが、カットポイントを指定するために指定された注釈でマークされているかどうか

たとえば、@ args(org.springframework.stereotype.Service)は、@ Serviceクラスパラメータでマークされたメソッドが1つしかないことを意味します

4.4 within()

クラス名でカットポイントを指定

たとえば、with(examples.chap03.Horseman)は、Horsemanのすべてのメソッドを意味します

4.5 target()

すべてのサブクラスを含むクラス名で指定

たとえば、target(examples.chap03.Horseman)とElephantmanがHorsemanを拡張すると、2つのクラスのすべてのメソッドが一致します。

4.6 @within()

指定されたアノテーションでマークされたクラスとそのすべてのサブクラスを一致させます

たとえば、@ within(org.springframework.stereotype.Service)は@ServiceアノテーションをHorsemanに追加し、HorsemanとElephantmanのすべてのメソッドが一致します。

4.7 @target()

指定された注釈でマークされたすべてのクラス

たとえば、@ target(org.springframework.stereotype.Service)は、@ Serviceでマークされたすべてのクラスのすべてのメソッドを意味します

4.8 this()

ほとんどの場合、target()と同じです。違いは、実行時にプロキシクラスが生成された後、プロキシクラスが指定されたオブジェクトタイプと一致するかどうかを判断することです。

5論理演算子
式は、論理演算によって複数のポイントカット関数で構成できます。

5.1 &&

そして、操作、交差点は、と書くこともできます

たとえば、execution(* chop(…))&& target(Horseman)は、Horsemanとそのサブクラスのchopメソッドを表します。

5.2 ||

または操作、ユニオンを見つける、またはとして書くこともできます

たとえば、execution(* chop(…))|| args(String)は、chopという名前のメソッド、またはString型パラメーターを持つメソッドを意味します。

5.3!

非操作、否定セットは、次のように記述することもできます。

たとえば、execution(* chop(…))および!args(String)は、chopという名前のメソッドを意味しますが、Stringパラメーターが1つしかないメソッドにすることはできません。

次の記事
@Enable *注釈付きソースコード、Springソースコード分析スケジュールされたタスクスケジュールされた注釈

おすすめ

転載: blog.csdn.net/u010010600/article/details/114116528
おすすめ