アノテーション、ネイティブ Spring、SchemaBased の 3 つの方法で AOP を実装する [詳細なケース付き]

目次

1. 構成 AOP に注釈を付ける

1. 注釈サポートを有効にする

2. クラスとメソッドにアノテーションを追加する

3. テスト

4. クラス内のすべてのメソッドの統一された構成ポイントカット

2. Native Spring は AOP を実装します

1. 依存関係を導入する

2. Spring AOP 通知クラスを作成する

3. 構成クラス bean2.xml を作成します。

4つのテスト

3. SchemaBasedによるAOPの実現

1. 構成面

2. テスト

過去のコラムや記事の関連記事 

1. Maven シリーズの列

2. Mybatisシリーズのコラム

3. スプリングシリーズのコラム


1. 構成 AOP に注釈を付ける

Spring では、構成ファイルの代わりにアノテーションを使用してアスペクトを構成できます。

1. 注釈サポートを有効にする

XML での AOP アノテーション サポートを有効にする

以下は bean1.xml ファイルです

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 扫描包 -->
    <context:component-scan base-package="com.example"></context:component-scan>
    <!-- 开启注解配置Aop -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

2. クラスとメソッドにアノテーションを追加する

注釈 @Aspect を通知クラス: 構成アスペクトの上に追加します。

通知メソッドの上に注釈を追加する

  • @Before: 事前アドバイス
  • @AfterReturning: 通知を投稿する
  • @AfterThrowing: 例外通知
  • @After: 最終通知
  • @Around: 通知の周囲

MyAspectAdvice アドバイス クラス 

package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspectJAdvice {

    // 后置通知
    @AfterReturning("execution(* com.example.dao.UserDao.*(..))")
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("切点方法名:"+joinPoint.getSignature().getName());
        System.out.println("目标对象:"+joinPoint.getTarget());
        System.out.println("打印日志···"+joinPoint.getSignature().getName()+"方法被执行了!");
    }

    // 前置通知
    @Before("execution(* com.example.dao.UserDao.*(..))")
    public void myBefore(){
        System.out.println("前置通知···");
    }

    // 异常通知
    @AfterThrowing(value = "execution(* com.example.dao.UserDao.*(..))",throwing = "e")
    public void myAfterThrowing(Exception e){
        System.out.println("异常通知···");
        System.out.println(e.getMessage());
    }

    // 最终通知
    @After("execution(* com.example.dao.UserDao.*(..))")
    public void myAfter(){
        System.out.println("最终通知···");
    }

    // 环绕通知
    @Around("execution(* com.example.dao.UserDao.*(..))")
    public Object myAround(ProceedingJoinPoint point) throws Throwable {
        System.out.println("环绕前···");
        // 执行方法
        Object obj = point.proceed();
        System.out.println("环绕后···");
        return obj;
    }
}

3. テスト

試験方法

    // 测试注解开发AOP
    @Test
    public void testAdd2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        //userDao.update();
        userDao.delete();
    }

テスト結果 (例外なし): 

update メソッドを使用して結果をテストします (例外あり)。 

この時点でプログラムが異常終了しているため、ラップ後の印刷がないことがわかります。 

4. クラス内のすべてのメソッドの統一された構成ポイントカット

クラス内のすべてのメソッドのポイントカットを均一に構成する方法:

通知クラスにメソッド構成ポイントカットを追加する

    // 添加方法配置切点
    @Pointcut("execution(* com.example.dao.UserDao.*(..))")
    public void pointcut(){

    }

定義されたポイントカットを通知メソッドで使用するには、注釈括弧内の内容を "pointCut()" に置き換えるだけです。

2. Native Spring は AOP を実装します

AspectJ に加えて、Spring は AOP をネイティブにサポートします。ただし、AOP を実装するネイティブな方法では、事前通知、事後通知、サラウンド通知、および例外通知の 4 種類の通知しかないことに注意してください。最終通知がありません。

1. 依存関係を導入する

        <!-- AOP -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.13</version>
        </dependency>

2. Spring AOP 通知クラスを作成する

Spring が AOP をネイティブに実装する場合、次の 4 つの通知タイプのみがサポートされます。

通知タイプ インターフェースを実装する
予告 メソッドBeforeAdvice
通知を投稿する 帰国後のアドバイス
例外通知 投げるアドバイス
サラウンド通知 メソッドインターセプター
package com.example.aspect;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {

    /**
     * 环绕通知
     * @param invocation 目标方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("环绕前");
        Object proceed = invocation.proceed();
        System.out.println("环绕后");
        return proceed;
    }

    /**
     * 后置通知
     * @param returnValue 目标方法的返回值
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("后置通知");
    }

    /**
     * 前置通知
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("前置通知");
    }

    /**
     * 异常通知
     * @param e 异常对象
     */
    public void afterThrowing(Exception e){
        System.out.println("发生异常了!");
    }
}

3. 構成クラス bean2.xml を作成します。

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.example"></context:component-scan>
    <!-- 通知对象 -->
    <bean id="springAop" class="com.example.aspect.SpringAop"/>

    <!-- 配置代理对象 -->
    <bean id="userDaoProxy"class="org.springframework.aop.framework.ProxyFactoryBean">                    
        <!-- 配置目标对象 -->
        <property name="target" ref="userDao"/>
        <!-- 配置通知 -->
        <property name="interceptorNames">
            <list>
                <value>springAop</value>
            </list>
        </property>
        <!-- 代理对象的生成方式 true:使用CGLib false:使用原生JDK生成 -->
        <property name="proxyTargetClass" value="true"/>
        <!-- bug -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
    </bean>
</beans>

4つのテスト

テストクラス UserDaoTest2

import com.example.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class userDaoTest2 {

    // 原生AOP测试
    @Test
    public void testAdd(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean2.xml");
        UserDao userDao = (UserDao) ac.getBean("userDaoProxy");
        userDao.update();
    }
}

試験結果 

        OK、ここにサプライズがあります、ここのクラスメートに当たったらわかるでしょう 

        実際、ラベルのバグは、ネイティブ メソッド構成クラスがそのラベルを追加することによってのみ識別できるためであり、それ以外の場合はエラーが報告されます。

3. SchemaBasedによるAOPの実現

        SchemaBased (基本モード) 構成メソッドは、Spring ネイティブ メソッドを使用して通知を定義し、AspectJ フレームワークを使用してアスペクトを構成することを指します。したがって、ここでの通知クラスは上記と同じです。上記を見てください。

1. 構成面

aop3.xml 設定ファイル

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.example"></context:component-scan>

    <!-- 通知对象 -->
    <bean id="springAop2" class="com.example.aspect.SpringAop"/>

    <!-- 配置切面 -->
    <aop:config>
        <!-- 配置切点 -->
        <aop:pointcut id="myPointcut" expression="execution(* com.example.dao.UserDao.*(..))"/>
        <!-- 配置切面:advice-ref:通知对象 pointcut-ref:切点 -->
        <aop:advisor advice-ref="springAop2" pointcut-ref="myPointcut"/>
    </aop:config>
</beans>

2. テスト

試験方法

    // 使用AspectJ框架配置切面测试
    @Test
    public void t6(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.add();
    }

試験結果

        OK、ここでの出力は、上で定義したものは完全ではなく、一部は繰り返し定義されている可能性があるため、繰り返し出力されるものをいくつか示します。 

過去のコラムや記事の関連記事 

     今回の内容が分からない方は、過去号もご覧ください。以下は、Maven や Mybatis など過去にブロガーが丁寧に書いたコラム記事です。あなたは通り過ぎます!役に立った場合は、「いいね」やブックマークをお願いします。このうち、Springコラムは一部更新中のため閲覧できませんが、ブロガーが全ての更新を完了すると閲覧できるようになります。

1. Maven シリーズの列

Maven シリーズのコラム Maven プロジェクト開発
Maven 集約開発 [例の詳細な説明 --- 5555 ワード]

2. Mybatisシリーズのコラム

Mybatisシリーズコラム MyBatis エントリー構成
Mybatisエントリーケース【超詳細】
MyBatis設定ファイル - 関連タグの詳細説明
Mybatis ファジー クエリ - パラメーターと集計クエリ、主キー バックフィルを定義する 3 つの方法
Mybatis 動的 SQL クエリ -- (実際の戦闘ケースを添付 -- 8888 ワード -- 88 品質ポイント)
Mybatis ページング クエリ - パラメーターを渡す 4 つの方法
Mybatis 1 次キャッシュおよび 2 次キャッシュ (テストメソッド付き)
Mybatis 分解クエリ
Mybatis関連のクエリ[実戦事例添付]
MyBatisアノテーション開発 --- 追加・削除・変更・動的SQLを実現
MyBatis アノテーション開発 --- カスタム マッピング関係と関連するクエリを実現します

3. スプリングシリーズのコラム

春の連載コラム Spring IOC の概要 [カスタム コンテナ インスタンス]
IOCがSpringを利用して実装する例を交えて詳しく解説
Spring IOCオブジェクトの作成方法、戦略、破棄タイミング、ライフサイクル、取得方法
Spring DIの紹介と依存性注入の方法と依存性注入の種類
Spring IOC 関連のアノテーションの適用—パート 1
Spring IOC 関連のアノテーションの適用—パート 2
Spring AOP と関連事例の紹介
アノテーション、ネイティブ Spring、SchemaBased の 3 つの方法で AOP を実装する [詳細なケース付き]
春季情勢と関連事例の紹介
Springトランザクション管理スキームとトランザクションマネージャーおよびトランザクション制御API
Spring トランザクション関連の設定、伝播動作、分離レベル、およびアノテーション設定の宣言型トランザクション

おすすめ

転載: blog.csdn.net/qq_53317005/article/details/129886638