アスペクト指向プログラミングアスペクト指向プログラミングは、oopオブジェクト指向プログラミングと比較して、Aopはプログラムコード内の特定のクラスまたは一部のメソッドに関係しなくなりましたが、aopは対面カット、つまり層間の一種の切断であるため、切断面と呼ばれます。みんなのハンバーガー(真ん中に肉が入っている)を考えてみてください。では、aopはどのようにして表面全体をインターセプトするのでしょうか?学習したサーブレットurlpattern / *の構成を考慮すると、実際にはaopの実現です。
SpringAopの実装方法
- 注釈方法
- XMLの方法
ケースプラクティス
注釈方法
jarパッケージ座標を導入します
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
Beans.xml構成
名前名を追加
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
Aopプロキシを構成する
<aop:aspectj-autoproxy/>
aop実装クラスを作成する
/**
* 声明切面组件
*/
@Component
@Aspect
public class LogCut {
/**
* 定义切入点 匹配方法规则定义
* 匹配规则表达式含义 拦截 com.xxx.service 包下 以及子包下 所有类的所有方法
*/
@Pointcut("execution (* com.xxx.service..*.*(..))")
public void cut(){
}
/**
* 声明前置通知 并将通知应用到定义的切入点上
* 目标类方法执行前 执行该通知
*/
@Before(value="cut()")
public void before(){
System.out.println("前置通知.....");
}
/**
* 声明返回通知 并将通知应用到切入点上
* 目标类方法执行完毕执行该通知
*/
@AfterReturning(value="cut()")
public void afterReturning(){
System.out.println("返回通知....");
}
/**
* 声明最终通知 并将通知应用到切入点上
* 目标类方法执行过程中是否发生异常 均会执行该通知 相当于异常中的 finally
*/
@After(value="cut()")
public void after(){
System.out.println("最终通知....");
}
/**
* 声明异常通知 并将通知应用到切入点上
* 目标类方法执行时发生异常 执行该通知
*/
@AfterThrowing(value="cut()",throwing="e")
public void afterThrowing(Exception e){
System.out.println("异常通知....方法执行异常时执行:"+e);
}
/**
* 声明环绕通知 并将通知应用到切入点上
* 方法执行前后 通过环绕通知定义相应处理
*/
@Around(value="cut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前置...");
System.out.println("环绕通知");
System.out.println(pjp.getTarget()+"--"+pjp.getSignature());
Object result=pjp.proceed();//执行目标对象方法
System.out.println("环绕后置...");
return result;
}
}
Aopマッチング法正規表現言語(簡単な理解)
Aopポイントカット式の概要
パブリックメソッドを実行します。
execution(public *(..))
任意の設定メソッドを実行します
execution(* set*(..))
com.xxx.serviceパッケージの下の任意のクラスの任意のメソッドを実行します
execution(* com.xxx.service.*.*(..))
com.xxx.serviceパッケージおよびサブパッケージの下にある任意のクラスの任意のメソッドを実行します
execution(* com.xxx.service..*.*(..))
xmlの方法
構成の側面、エントリポイント、通知
<!-- aop 相关配置 -->
<aop:config>
<!-- aop 切面配置 -->
<aop:aspect ref="logCut">
<!-- 定义 aop 切入点 -->
<aop:pointcut expression="execution (* com.xxx.service..*.*(..))"
id="cut"/>
<!-- 配置前置通知 指定前置通知方法名 并引用切入点定义 -->
<aop:before method="before" pointcut-ref="cut"/>
<!-- 配置返回通知 指定返回通知方法名 并引用切入点定义 -->
<aop:after-returning method="afterReturning" pointcut-ref="cut"/>
<!-- 配置异常通知 指定异常通知方法名 并引用切入点定义 -->
<aop:after-throwing method="afterThrowing" throwing="e" pointcut-ref="cut"/>
<!-- 配置最终通知 指定最终通知方法名 并引用切入点定义 -->
<aop:after method="after" pointcut-ref="cut"/>
<!-- 配置环绕通知 指定环绕通知方法名 并引用切入点定义 -->
<aop:around method="around" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
Beanを定義する
/**
* 声明切面组件
*/
@Component
public class LogCut {
public void before(){
System.out.println("前置通知.....");
}
public void afterReturning(){
System.out.println("返回通知....");
}
public void after(){
System.out.println("最终通知....");
}
public void afterThrowing(Exception e){
System.out.println("异常通知....方法执行异常时执行:" + e);
}
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前置...");
System.out.println("环绕通知");
System.out.println(pjp.getTarget()+"--"+pjp.getSignature());
Object result=pjp.proceed();
System.out.println("环绕后置...");
return result;
}
}
展開
AOPの基本概念
JoinPoint(接続ポイント)【ダイナミック】
インターセプトされるすべてのポイント、スプリングミドルはインターセプトされるすべてのメソッドを指し、スプリングaopの接続ポイントはメソッドの実行を表します。
ポイントカット(エントリーポイント)[静的]
接続ポイントのインターセプトの定義(マッチングルール定義は、インターセプトされるメソッドと処理されるメソッドを指定します)のために、springには特別な式言語定義があります。
アドバイス{強調}
操作の前後にすべての接続ポイント(各メソッド)をインターセプトします
- 事前通知(事前拡張)–実行メソッドの前のbefore()通知
- 返品通知(返品拡張)-afterReturningメソッドが正常に終了して戻る後の通知
- 例外スロー通知(拡張例外スロー)–afetrThrow()
- 最終通知-メソッドが異常であるかどうかに関係なく、通知が実行された後
- アドバイス周辺-メソッド呼び出しなどの結合ポイント(結合ポイント)アドバイス周辺。これは最も強力なタイプの通知です。サラウンド通知は、メソッド呼び出しの前後にカスタム動作を完了することができます。また、接続ポイントの実行を続行するか、独自の戻り値を直接返すか、例外をスローして実行を終了するかを選択します。
側面
エントリポイントと通知の組み合わせにより、アスペクトの定義が決まります。エントリポイントは、どのクラスのどのメソッドをインターセプトするかを定義します。通知は、インターセプトメソッドの後に何をするかを定義します。アスペクトは、クラスと同様に、分野横断的な懸念事項を抽象化したものです。クラスはオブジェクトの特性の抽象化であり、アスペクトは分野横断的な懸念の抽象化です。
目標
対象者
織り(織り)
アスペクトをターゲットオブジェクトに適用し、プロキシオブジェクトを生成するプロセスは、ウィービング(プロセス)と呼ばれます。
前書き
元のアプリケーションコードを変更せずに、プログラムの実行時にメソッドまたはフィールドをクラスに動的に追加するプロセスは、導入と呼ばれます。