1.AOPの運用条件
2.AOPの準備
1. Springフレームワークは通常、AOP操作を実装するためにAspectJに基づいています
AspectJはSpringの独立したAOPフレームワークの一部ではなく、通常、AspectJとSpirngフレームワークを一緒に使用してAOP操作を実行します。
2.AspectJに基づくAOP操作
(1)xml構成ファイルに基づく実装
(2)注釈方法に基づく実装(使用)
3プロジェクトエンジニアリングにAOP関連の依存関係を導入する
4.ポイントカット式
(1)エントリポイント式の機能:
どのクラスのどのメソッドを強化するかを知る
(2)文法構造:
execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]))
[权限修饰符]:public,private,*
[返回类型] 可以不写
[类全路径]
[方法名称]([参数列表])
例1:
对 com.atguigu.dao.BookDao 类里面的 add进行增强
execution(* com.atguigu.dao.BookDao.add(..))
例2:
对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强
execution(* com.atguigu.dao.BookDao.* (..))
例3:
对 com.atguigu.dao包里面所有类,类里面所有方法进行增强
execution(* com.atguigu.dao.*.* (..))
3.AOP操作を実現するためのAspectJアノテーション
1.クラスを作成します
2.拡張クラスを作成します(拡張ロジックを記述します)
package com.LinXiaoDe.spring5.aopanno;
//增强的类
public class UserProxy {
//前置通知
public void before(){
System.out.println("before");
}
}
3.通知を構成します
(1)注釈スキャンを開くには2つの方法があります。
1つは、構成ファイルを介して注釈スキャンをオンにすることであり、もう1つは、新しい構成クラスを介して注釈スキャンをオンにすることです。
①設定ファイルの注釈スキャンを有効にする
- 名前名を導入し、注釈スキャンをオンにします。
②新しい構成クラスを作成して注釈スキャンを有効にする
@Configuration @ComponentScan(basePackages = {
"com.atguigu"}) @EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}
(2)注釈を使用してUserオブジェクトとUserProxyオブジェクトを作成します
(3)拡張クラスに注釈@Aspectを追加します
(4)Spring構成ファイルでプロキシオブジェクトの生成をオンにします
(5)さまざまなタイプの通知を構成する
拡張クラスで、通知メソッドの上に通知タイプの注釈を追加し、エントリポイント式の構成を使用します
execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]))
package com.LinXiaoDe.spring5.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//增强的类
@Component
@Aspect //要生成代理对象
public class UserProxy {
//@Before表示前置通知
@Before(value="execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void before(){
System.out.println("Before 前置通知");
}
//后置通知(返回通知)
@AfterReturning(value="execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void afterReturning(){
System.out.println("afterReturning后置通知");
}
//@After表示最终通知
@After(value="execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void after(){
System.out.println("after最终通知");
}
//AfterThrowing表示异常通知
@AfterThrowing(value="execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void afterThrowing(){
System.out.println("afterThrowing");
}
//环绕通知
@Around(value="execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("环绕之前");
//被增强的方法
proceedingJoinPoint.proceed();
System.out.println("环绕之后");
}
}
4.同じエントリポイントを抽出します
@Pointcutを使用して同じエントリポイントを抽出します(文字列の保存も可能です)
package com.LinXiaoDe.spring5.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//增强的类
@Component
@Aspect //要生成代理对象
public class UserProxy {
//对相同的切入点进行抽取
@Pointcut(value = "execution(* com.LinXiaoDe.spring5.aopanno.User.add())")
public void pointdemo(){
}
//@Before表示前置通知
@Before(value="pointdemo()")
public void before(){
System.out.println("Before 前置通知");
}
//后置通知(返回通知)
@AfterReturning(value="pointdemo()")
public void afterReturning(){
System.out.println("afterReturning后置通知");
}
}
5.同じメソッドで拡張する複数の拡張クラスがあり、拡張クラスの優先度を設定します
- 注釈@Order(数値タイプ値)を拡張クラスに追加します。数値タイプ値が小さいほど、優先度が高くなります。
@Component
@Aspect
@Order(1)//优先级
public class PersonProxy {
}