Spring AOP の基本的な実装原則

序文

AOP も Spring の比較的重要なコンテンツです. 従来の OOP モードと比較すると, AOP には理解できない部分がたくさんあります. この記事では, AOP の実装方法とその基礎となる実装を紹介します.

  • 初期 AOP
  • AOP の基本概念
  • AOP (概念) 用語
  • 動的プロキシ
  • 通知の概要 (プレ、ポスト、リターン、例外、サラウンド)
  • 注釈ベースの構成通知
  • AOP の適用シナリオ

1.AOPとは

AOP (Aspect-Oriented Programming)、つまりアスペクト指向プログラミングは、OOP (Object-Oriented Programming、オブジェクト指向プログラミング) を補完し、OOP とは異なる抽象的なソフトウェア構造の観点を提供します. OOP では、クラスを次のように使用します。私たちの基本単位であり、AOP の基本単位は Aspect (アスペクト) です

第二に、AOPの基本概念

AOP フレームワークには、次の 2 つの特徴があります。

  1. 複数のステップ間の良好な分離。
  2. ソース コードの独立性。

3. AOP の概念 (AOP 用語)

側面・アドバイザー(セクション)

複数のオブジェクトをクロスカットする可能性のある懸念事項のモジュール化。Spring AOP では、パターンベースまたは @Aspect アノテーションベースのメソッドを使用してアスペクトを実装できます。

参加ポイント

プログラム実行中のポイント。Spring AOP では、ジョイン ポイントは常にメソッドの実行を表します。

アドバイス

アスペクトの特定の結合ポイントで実行されるアクション。多くの AOP フレームワーク (Spring を含む) は、通知モデルとしてインターセプターを使用し、結合ポイントを中心としたインターセプターのチェーンを維持します。

ポイントカット(エントリーポイント)

結合点の条件を見つけます。アドバイスはポイントカット式に関連付けられており、このポイントカットを満たす結合ポイントで動作します。

序章

型で追加のメソッドまたはプロパティを宣言します。Spring では、プロキシされたオブジェクトに新しいインターフェイス (および対応する実装) を導入できます。

対象物

1 つまたは複数の側面からアドバイスを受けるオブジェクト。推奨オブジェクトとも呼ばれます。Spring AOP はランタイム プロキシを介して実装されるため、このオブジェクトは常にプロキシされたオブジェクトです。

AOP プロキシ

AOP フレームワークによって作成されたオブジェクトは、アスペクト コントラクト (通知メソッドの実行など) を実装するために使用されます。Spring では、AOP プロキシは JDK 動的プロキシまたは CGLIB プロキシにすることができます。

製織

ウィービングは、AOP プロキシ オブジェクトを作成するためにターゲット オブジェクトにアスペクトを適用するプロセスです. ウィービングは、コンパイル、クラスのロード、および実行時に実行できます。

春のAOP

1. Spring AOP は純粋な Java で実装されているため、特別なコンパイル プロセスは必要ありません。Spring AOP はクラス ローダー階層の制御を必要としないため、サーブレット コンテナーまたはアプリケーション サーバーに適しています。

2. Spring AOP は現在、メソッド実行のジョイン ポイントのみをサポートしています。

3. Spring が AOP を実装する方法は、他のフレームワークとは異なります。Spring は、最も完全な AOP 実装を提供するつもりはありません (Spring AOP にはこの機能がありますが)。それどころか、実際には、AOP 実装と Spring IC コンテナーとの間の統合を提供して、エンタープライズレベルの開発の一般的な問題を解決することに焦点を当てています。

4. Spring AOP は、包括的な AOP ソリューションを提供することで AspectJ と競合するつもりはありません。Spring AOP などのプロキシベースのフレームワークや AspectJ などの成熟したフレームワークはどちらも価値があり、競合ではなく補完的であるべきだと考えています。

4 つ目は、Spring フレームワークでの AOP の基本的な実装です。

 Srping フレームワークの AOP テクノロジーの最下層は、使用されるプロキシ テクノロジーでもあります。

1. JDK ベースの動的エージェント

インターフェイス指向である必要があり、特定のインターフェイスを実装するクラスのみがプロキシ オブジェクトを生成できます

2. CGLIB に基づく動的プロキシ

インターフェイスを実装しないクラスの場合、プロキシを生成して、このクラスのサブクラスを生成することもできます

Spring の従来の AOP は、クラスがインターフェースを実装するかどうかに応じて、異なるプロキシ メソッドを採用します。

  • クラス インターフェイスが実装されている場合は、JDK 動的プロキシを使用して AOP を完成させます。
  • インターフェイスが実装されていない場合は、CGLIB 動的プロキシを使用して AOP を完了します

Spring に基づく AOP の単純な実装

説明の前に、Spring AOP を使用してコードを正常に実行するには、Spring が開発者に提供する jar パッケージだけを使用するだけでは十分ではなく、インターネットから 2 つの追加の jar パッケージをダウンロードしてください:

  1. aopalliance.jar
  2. アスペクトjweaver.jar

5. 構成による aop 通知の効果の実現

xml 構成

<bean id="logger" class="com.ahpome.company.utils.Logger" />
<aop:config>
	// 定义切面 aspect
	<aop:aspect id="loggerAspect" ref="logger"> 
		// 定义 切入点
		<aop:pointcut id="loggerRef" expression="execution(* com.ahpome.company..*.*(..)) and !bean(logger)" />
		// 通知 环绕通知 :around;前置通知 :before;后置通知:after;最终通知:after-returning;异常通知:after-throwing
		<aop:around method="record" pointcut-ref="loggerRef" />
	</aop:aspect>
</aop:config>
	public Object record(ProceedingJoinPoint pjp){

		Log log = new Log();

		try {
			log.setOperator("admin");
			String mname = pjp.getSignature().getName();
			log.setOperName(mname);
			Object[] args = pjp.getArgs();
			log.setOperParams(Arrays.toString(args));

			// 执行目标方法,返回的是目标方法的返回值,本例中 void
			Object obj = pjp.proceed();
			if(obj != null){
				log.setResultMsg(obj.toString());
			}else{
				log.setResultMsg(null);
			}

			log.setOperResult("success");
			System.out.println("1111");

			return obj;
		} catch (Throwable e) {
			log.setOperResult("failure");
			log.setResultMsg(e.getMessage());
		} finally{
			// logService.saveLog(log);
		}
		// 注意:这里如果是返回null即使你调用的时候返回是null,即使你的方法中含有返回值
		return null;
	}

JDK 動的プロキシ

	/*
	 * 接口
	 */
	public interface UserService {
		void save();
		int select();
	}
    /*
	 * 接口实现类
	 */
	public class UserServiceImpl implements UserService {

		@Override
		public void save() {
			System.out.println("保存用户信息成功");
		}

		@Override
		public int select() {
			System.out.println("查询用户信息成功");
			return 10;
		}
	}

	/*
	 * JDK动态代理工厂类
	 */
	public class JdkProxyFactory implements InvocationHandler {
		private Object target;
		public JdkProxyFactory(Object target) {
			this.target = target;
		}

		/**
		 * 获取代理对象,当前类继承InvocationHandler
		 */
		public Object getProxyObject() {
			return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			//添加功能
			System.out.println("增强代码,添加日志功能");
			//执行原有方法
			return method.invoke(target, args);
		}
	}

JDK 動的プロキシをテストする

	@Test
	public void JdkProxyTest() {

		// 创建目标对象
		UserService userService = new UserServiceImpl();
		//创建工厂对象
		JdkProxyFactory jdkProxyFactory = new JdkProxyFactory(userService);
		UserService proxy = (UserService) jdkProxyFactory.getProxyObject();
		proxy.save();
		System.out.println("=========================");
		proxy.select();
		
	}

6. AOP の適用シナリオ

前述のとおり、AOP は主にコア以外のビジネス ロジックに適用されますが、AOP の一般的なアプリケーション シナリオを見てみましょう。

  • モニター
  • ログ
  • キャッシュ
  • 認証
  • 事務
  • 例外処理
  • 持久化

要約する

上記は、大規模なインターネット アーキテクチャの Java 開発における Spring AOP の実装に関する基本的な問題の概要です。Spring AOP の実装原則。

おすすめ

転載: blog.csdn.net/gongzi_9/article/details/126297378