(9)侵入から土壌への春-AOPはそれと同じくらい簡単です

AOP

AOPとは

アスペクト指向プログラミング。実行時のプリコンパイルと動的エージェントにより、プログラム機能の統一保守を実現する技術。AOPはOOPの続きであり、ソフトウェア開発のホットスポットであり、Springフレームワークの重要なコンテンツです。関数型プログラミングの派生ジェネリックです。AOPを使用すると、ビジネスロジックのさまざまな部分を分離できるため、ビジネスロジックが作成されます。各部の結合度が低下し、プログラムの再利用性が向上すると同時に、開発効率も向上します。

春のAOPの役割

  • 宣言型トランザクションを提供し、ユーザーがアスペクトをカスタマイズできるようにします

コア名詞

  • 横断的関心事:アプリケーションの複数のモジュールにまたがるメソッドまたは関数。つまり、ビジネスロジックとは何の関係もありませんが、注意が必要なのは、ログ、セキュリティ、キャッシュ、トランザクションなどの横断的関心事です。
  • 側面:横断的な焦点がモジュール化されている特徴的なオブジェクト、すなわち:それはクラスです
  • 注意:セクションで実行する必要のある作業。つまり、それはクラスのメソッドです
  • ターゲット:通知される
  • プロキシ:将来作成されるオブジェクトをターゲットオブジェクトアプリケーションに通知します。
  • エントリポイント:アスペクト通知を実装するための「場所の定義」
  • 接続ポイント:エントリポイントと一致する実行ポイント

Springでサポートされる5種類のアドバイス

通知タイプ ジャンクション インターフェイスを実装する
予告 メソッドの前 MethodBeforeAdvice
通知を投稿する メソッドの後 AfterReturningAdvice
サラウンド通知 メソッドの前後 MethodInterceptor
例外スロー通知 メソッドは例外をスローします ThrowsAdvice
紹介通知 クラスに新しいメソッド属性を追加します はじめにOnterceptor

つまり、Aopは元のコードを変更せずに新しい関数を追加します

Springを使用してAopを実装する

AOPを使用するには、依存関係パッケージをインポートする必要があります

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.4</version>
</dependency>

最初の方法-SpringAPIを介して

ビジネスインターフェイスと実装クラス
public interface UserService {

   public void add();

   public void delete();

   public void update();

   public void search();

}
public class UserServiceImpl implements UserService{

   @Override
   public void add() {
       System.out.println("增加用户");
  }

   @Override
   public void delete() {
       System.out.println("删除用户");
  }

   @Override
   public void update() {
       System.out.println("更新用户");
  }

   @Override
   public void search() {
       System.out.println("查询用户");
  }
}
強化されたクラス
事前拡張
public class Log implements MethodBeforeAdvice {

   //method : 要执行的目标对象的方法
   //objects : 被调用的方法的参数
   //Object : 目标对象
   @Override
   public void before(Method method, Object[] objects, Object o) throws Throwable {
       System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
  }
}
ポストエンハンスメント
public class AfterLog implements AfterReturningAdvice {
   //returnValue 返回值
   //method被调用的方法
   //args 被调用的方法的对象的参数
   //target 被调用的目标对象
   @Override
   public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
       System.out.println("执行了" + target.getClass().getName()
       +"的"+method.getName()+"方法,"
       +"返回值:"+returnValue);
  }
}
Springファイルに移動して、aopカットイン実装を登録および実装します
<?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.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

   <!--注册bean-->
   <bean id="userService" class="com.zhonghu.service.UserServiceImpl"/>
   <bean id="log" class="com.zhonghu.log.Log"/>
   <bean id="afterLog" class="com.zhonghu.log.AfterLog"/>

   <!--aop的配置-->
   <aop:config>
       <!--切入点 expression:表达式匹配要执行的方法 -->
       <aop:pointcut id="pointcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/>
       <!--执行环绕增强; advice-ref执行方法 . pointcut-ref切入点-->
       <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
       <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
   </aop:config>

</beans>  
テスト
public class MyTest {
   @Test
   public void test(){
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       // 动态代理代理的是接口
       UserService userService = (UserService) context.getBean("userService");
       userService.search();
  }
}

Aopの重要性:非常に重要です。アイデアを理解する必要があります

Spring'sAopは、パブリックビジネス(ロギング、セキュリティ)とドメインビジネスを組み合わせることです。ドメインビジネスを実行すると、パブリックビジネスが追加され、パブリックビジネスの再利用が実現します。ドメインビジネスはより純粋で、プログラマーはフィールドビジネスに集中するだけで済みます。 。

その本質は依然として動的エージェントです

2番目の方法:Aopを達成するためのカスタムクラス

ターゲットビジネスはuserServiceImplと同じままです

クラスにカット
public class DiyPointcut {

   public void before(){
       System.out.println("---------方法执行前---------");
  }
   public void after(){
       System.out.println("---------方法执行后---------");
  }

}
スプリング構成に移動
<!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.zhonghu.config.DiyPointcut"/>

<!--aop的配置-->
<aop:config>
   <!--第二种方式:使用AOP的标签实现-->
   <aop:aspect ref="diy">
       <aop:pointcut id="diyPonitcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/>
       <aop:before pointcut-ref="diyPonitcut" method="before"/>
       <aop:after pointcut-ref="diyPonitcut" method="after"/>
   </aop:aspect>
</aop:config>
テスト
public class MyTest {
   @Test
   public void test(){
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       UserService userService = (UserService) context.getBean("userService");
       userService.add();
  }
}

3番目の方法-注釈を使用する

アノテーション実装用の拡張クラス
package com.zhonghu.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

// 标注这个类是一个切面
// 标注这个类是一个切面
@Aspect
public class PointCut {

    @Before("execution(* com.zhonghu.pojo.User.*(..))")
    public void befer(){
        System.out.println("方法执行前");
    }

    @After("execution(* com.zhonghu.pojo.User.*(..))")
    public void after(){
        System.out.println("方法执行后");
    }
    //在环绕增强中,我们可以给定一个参数,代表我们要处理切入的点。
    @Around("execution(* com.zhonghu.pojo.User.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前");
        System.out.println("签名:"+jp.getSignature());
        //执行目标方法proceed
        Object proceed = jp.proceed();
        System.out.println("环绕后");
        System.out.println(proceed);
    }
}
Spring構成ファイルで、Beanを登録し、アノテーションをサポートする構成を追加します
<!--第三种方式:注解实现-->
<bean id="annotationPointcut" class="com.zhonghu.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>

出力結果:

画像

アスペクトの実行順序:

画像

aop:aspectj-autoproxy:説明

  • aopによって作成された名前空間の<aop:aspectj-autoproxy />宣言は、Springコンテナー内の@aspectJアスペクトで構成されたBeanのプロキシーを自動的に作成し、アスペクトに織り込みます。もちろん、Springは引き続きAnnotationAwareAspectJAutoProxyCreatorを内部的に使用して自動プロキシを作成しますが、特定の実装の詳細は<aop:aspectj-autoproxy />によって隠されています。
  • <aop:aspectj-autoproxy />にはproxy-target-class属性があり、デフォルトはfalseです。これは、<aop:aspectj-autoproxy poxy-target-class = "trueとして構成されている場合、jdk動的プロキシウィービング拡張機能を使用することを意味します。 "/>当時、それはCGLib動的プロキシテクノロジーを使用して織り込み、強化することを意味します。ただし、proxy-target-classがfalseに設定されている場合でも、ターゲットクラスがインターフェイスを宣言していない場合、Springは自動的にCGLib動的プロキシを使用します。

やっと

  • 読んでやりがいを感じたら、いいねをあげたいと思います。これが更新の最大のモチベーションになります。ご支援ありがとうございます。
  • Javaとコンピュータの基本的な知識に焦点を当てた私の公開アカウント[JavaFox]に注目してください。私を信じていない場合は、私を叩いてください。
  • 読んだ後に異なる意見や提案がある場合は、コメントして私たちと共有してください。皆様のご支援、ご愛顧を賜りますようお願い申し上げます。

画像

最新ニュースについては、パブリックアカウント「JavaFox」をフォローすることを歓迎します

おすすめ

転載: blog.csdn.net/issunmingzhi/article/details/112548462