ホームページ >Java >&#&チュートリアル >SpringBootプロジェクトでaopを使用する方法

SpringBootプロジェクトでaopを使用する方法

王林
王林転載
2023-05-11 15:04:131658ブラウズ

はじめに

IOC と AOP は Spring の 2 つの中心的な概念です。私の理解を簡単に紹介します:

IOC: 制御の反転、つまりオブジェクト プロセスを手動で作成します。 Spring は、オブジェクトの生成、オブジェクトの管理、オブジェクトとオブジェクト間の依存関係の管理に役立ちます。これにより、コードの結合が軽減され、後のプロジェクトのメンテナンスが容易になります。より一般的な例を挙げると、次のようになります。
通常の状況では、私たちは家にいて、お腹を空かせて、自分で料理をします。
IOCを利用する場合、家にいてお腹が空いたときに業者に電話すると食べ物が届けられます。
IOC は販売者に相当し、料理はオブジェクトの作成に相当します。
つまり、通常の状況では、クラスが他のクラスのメソッドを呼び出す必要がある場合、新しいメソッド、ファクトリーメソッド、またはその他のメソッドを使用してオブジェクトを手動で作成します。
IOC を使用する場合、必要なのはオブジェクトを挿入することだけです。

AOP: アスペクト指向 (便利な) プログラミング。特定の種類のオブジェクトを監視および制御し、この種類のオブジェクトのメソッドを呼び出す前後に指定されたコードを呼び出すことで、メソッドを拡張して拡張を実現できます。モジュール機能の影響。簡単な例を挙げると、次のようになります。
通常の状況では、直接食事をします。
AOP を使用すると、乳母があなたを見守り、食事前の手洗いや食後の食器の片付けを手伝ってくれます。
AOP は乳母に相当し、食事は特定のメソッドの呼び出しに相当します。
つまり、メソッドを補完したい場合、メソッドを直接変更するのではなく、AOP を通じて補完します。補充したくない場合、または補充を交換する必要がある場合は、AOP を直接操作できます。
1. ポイントカット: ポイントカット、execution(* cn.springcamp.springaop.service..(…)) など、どのメソッドがインターセプトされるかを定義するために使用されます

2. アドバイス: インターセプトされたメソッドのアクション

##3. アスペクト: アスペクト、ポイントカットとアドバイスを組み合わせてアスペクトを形成します

##4. 結合ポイント: 実行中のポイントカットのインスタンス

4. ウィーバー: AspectJ や Spring AOP などの AOP を実装するフレームワーク

1. SpringBoot プロジェクトでは AOP の依存関係が導入されています

<!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

スタートアップ クラスには @EnableAspectJAutoProxy アノテーションが追加されますが、これは省略可能です。 AOP のデフォルト構成プロパティでは、 spring.aop.auto プロパティがデフォルトでオンになっているためです。

AspectJ の依存関係を導入する必要はもうありません。


2. 通常のメソッド

アスペクトクラスコード:

package com.example.myblog.test;


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

@Component
@Aspect
public class AOPTest {
    //定义切入点
    @Pointcut("execution(public * com.example.myblog.test.AOPTestClient.*(..))")
    public void aspectTest(){}

    //前置通知,切入点执行之前执行
    @Before("aspectTest()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("前置通知");
    }
    //后置通知,切入点执行之后执行
    @After("aspectTest()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("后置通知");
    }
    //最终通知,,切入点执行之后执行
    @AfterReturning("aspectTest()")
    public void doAfterReturning(JoinPoint joinPoint){
        System.out.println("最终通知");
    }
    //异常通知,切入点抛出异常执行
    @AfterThrowing("aspectTest()")
    public void deAfterThrowing(JoinPoint joinPoint){
        System.out.println("异常通知");
    }
    //环绕通知,切入点执行前、后执行
    @Around("aspectTest()")
    public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("未执行");
        Object result = joinPoint.proceed();
        System.out.println("已执行");
        //返回结果
        return result;
    }
}

ポイントカットクラスコード:

package com.example.myblog.test;

import org.springframework.stereotype.Component;

@Component
public class AOPTestClient {
    public void test(){
        System.out.println("正在测试AOP");
    }
}

テストクラスコード:

package com.example.myblog;

import com.example.myblog.test.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class MyblogApplicationTests {
    
    @Autowired
    private AOPTestClient aopTestClient;

    @Test
    public void testAOP(){
        aopTestClient.test();
    }
}

テスト結果:

SpringBootプロジェクトでaopを使用する方法3. アノテーション メソッド

カスタム アノテーション コード:

package com.example.myblog.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//表示次注解可以标注在类和方法上
@Target({ElementType.METHOD, ElementType.TYPE})
//运行时生效
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    //定义一个变量,可以接受参数
    String desc() default " ";
}

Aspect クラス コード:

package com.example.myblog.test;

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

@Component
@Aspect
public class AOPAnnotationTest {
    //定义切入点
    @Pointcut("@annotation(com.example.myblog.test.MyAnnotation)")
    public void aspectTest(){}

    //前置通知,切入点执行之前执行
    @Before("aspectTest()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("前置通知");
    }
    //后置通知,切入点执行之后执行
    @After("aspectTest()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("后置通知");
    }
    //最终通知,,切入点执行之后执行
    @AfterReturning("aspectTest()")
    public void doAfterReturning(JoinPoint joinPoint){
        System.out.println("最终通知");
    }
    //异常通知,切入点抛出异常执行
    @AfterThrowing("aspectTest()")
    public void deAfterThrowing(JoinPoint joinPoint){
        System.out.println("异常通知");
    }
    //环绕通知,切入点执行前、后执行
    @Around("aspectTest()")
    public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("未执行");
        Object result = joinPoint.proceed();
        System.out.println("已执行");
        //返回结果
        return result;
    }
}

Pointcutクラス コード:

package com.example.myblog.test;

import org.springframework.stereotype.Component;

@Component
public class AOPAnnotationTestClient {
    @MyAnnotation
    public void test(){
        System.out.println("正在测试AOP");
    }
}

テスト クラス コード:

@Test
    public void testAOPAnnotation(){
        aopAnnotationTestClient.test();
    }

テスト結果:

以上がSpringBootプロジェクトでaopを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。