目次
4. クラス内のすべてのメソッドの統一された構成ポイントカット
1. 構成 AOP に注釈を付ける
Spring では、構成ファイルの代わりにアノテーションを使用してアスペクトを構成できます。
1. 注釈サポートを有効にする
XML での AOP アノテーション サポートを有効にする
以下は bean1.xml ファイルです
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 扫描包 --> <context:component-scan base-package="com.example"></context:component-scan> <!-- 开启注解配置Aop --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
2. クラスとメソッドにアノテーションを追加する
注釈 @Aspect を通知クラス: 構成アスペクトの上に追加します。
通知メソッドの上に注釈を追加する
- @Before: 事前アドバイス
- @AfterReturning: 通知を投稿する
- @AfterThrowing: 例外通知
- @After: 最終通知
- @Around: 通知の周囲
MyAspectAdvice アドバイス クラス
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspectJAdvice {
// 后置通知
@AfterReturning("execution(* com.example.dao.UserDao.*(..))")
public void myAfterReturning(JoinPoint joinPoint){
System.out.println("切点方法名:"+joinPoint.getSignature().getName());
System.out.println("目标对象:"+joinPoint.getTarget());
System.out.println("打印日志···"+joinPoint.getSignature().getName()+"方法被执行了!");
}
// 前置通知
@Before("execution(* com.example.dao.UserDao.*(..))")
public void myBefore(){
System.out.println("前置通知···");
}
// 异常通知
@AfterThrowing(value = "execution(* com.example.dao.UserDao.*(..))",throwing = "e")
public void myAfterThrowing(Exception e){
System.out.println("异常通知···");
System.out.println(e.getMessage());
}
// 最终通知
@After("execution(* com.example.dao.UserDao.*(..))")
public void myAfter(){
System.out.println("最终通知···");
}
// 环绕通知
@Around("execution(* com.example.dao.UserDao.*(..))")
public Object myAround(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕前···");
// 执行方法
Object obj = point.proceed();
System.out.println("环绕后···");
return obj;
}
}
3. テスト
試験方法
// 测试注解开发AOP
@Test
public void testAdd2(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
//userDao.update();
userDao.delete();
}
テスト結果 (例外なし):
update メソッドを使用して結果をテストします (例外あり)。
この時点でプログラムが異常終了しているため、ラップ後の印刷がないことがわかります。
4. クラス内のすべてのメソッドの統一された構成ポイントカット
クラス内のすべてのメソッドのポイントカットを均一に構成する方法:
通知クラスにメソッド構成ポイントカットを追加する
// 添加方法配置切点 @Pointcut("execution(* com.example.dao.UserDao.*(..))") public void pointcut(){ }
定義されたポイントカットを通知メソッドで使用するには、注釈括弧内の内容を "pointCut()" に置き換えるだけです。
2. Native Spring は AOP を実装します
AspectJ に加えて、Spring は AOP をネイティブにサポートします。ただし、AOP を実装するネイティブな方法では、事前通知、事後通知、サラウンド通知、および例外通知の 4 種類の通知しかないことに注意してください。最終通知がありません。
1. 依存関係を導入する
<!-- AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.13</version>
</dependency>
2. Spring AOP 通知クラスを作成する
Spring が AOP をネイティブに実装する場合、次の 4 つの通知タイプのみがサポートされます。
通知タイプ インターフェースを実装する 予告 メソッドBeforeAdvice 通知を投稿する 帰国後のアドバイス 例外通知 投げるアドバイス サラウンド通知 メソッドインターセプター
package com.example.aspect;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {
/**
* 环绕通知
* @param invocation 目标方法
* @return
* @throws Throwable
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕前");
Object proceed = invocation.proceed();
System.out.println("环绕后");
return proceed;
}
/**
* 后置通知
* @param returnValue 目标方法的返回值
* @param method 目标方法
* @param args 目标方法的参数列表
* @param target 目标对象
* @throws Throwable
*/
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置通知");
}
/**
* 前置通知
* @param method 目标方法
* @param args 目标方法的参数列表
* @param target 目标对象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置通知");
}
/**
* 异常通知
* @param e 异常对象
*/
public void afterThrowing(Exception e){
System.out.println("发生异常了!");
}
}
3. 構成クラス bean2.xml を作成します。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.example"></context:component-scan>
<!-- 通知对象 -->
<bean id="springAop" class="com.example.aspect.SpringAop"/>
<!-- 配置代理对象 -->
<bean id="userDaoProxy"class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目标对象 -->
<property name="target" ref="userDao"/>
<!-- 配置通知 -->
<property name="interceptorNames">
<list>
<value>springAop</value>
</list>
</property>
<!-- 代理对象的生成方式 true:使用CGLib false:使用原生JDK生成 -->
<property name="proxyTargetClass" value="true"/>
<!-- bug -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</bean>
</beans>
4つのテスト
テストクラス UserDaoTest2
import com.example.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class userDaoTest2 {
// 原生AOP测试
@Test
public void testAdd(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean2.xml");
UserDao userDao = (UserDao) ac.getBean("userDaoProxy");
userDao.update();
}
}
試験結果
OK、ここにサプライズがあります、ここのクラスメートに当たったらわかるでしょう
実際、ラベルのバグは、ネイティブ メソッド構成クラスがそのラベルを追加することによってのみ識別できるためであり、それ以外の場合はエラーが報告されます。
3. SchemaBasedによるAOPの実現
SchemaBased (基本モード) 構成メソッドは、Spring ネイティブ メソッドを使用して通知を定義し、AspectJ フレームワークを使用してアスペクトを構成することを指します。したがって、ここでの通知クラスは上記と同じです。上記を見てください。
1. 構成面
aop3.xml 設定ファイル
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.example"></context:component-scan>
<!-- 通知对象 -->
<bean id="springAop2" class="com.example.aspect.SpringAop"/>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="myPointcut" expression="execution(* com.example.dao.UserDao.*(..))"/>
<!-- 配置切面:advice-ref:通知对象 pointcut-ref:切点 -->
<aop:advisor advice-ref="springAop2" pointcut-ref="myPointcut"/>
</aop:config>
</beans>
2. テスト
試験方法
// 使用AspectJ框架配置切面测试
@Test
public void t6(){
ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.add();
}
試験結果
OK、ここでの出力は、上で定義したものは完全ではなく、一部は繰り返し定義されている可能性があるため、繰り返し出力されるものをいくつか示します。
過去のコラムや記事の関連記事
今回の内容が分からない方は、過去号もご覧ください。以下は、Maven や Mybatis など過去にブロガーが丁寧に書いたコラム記事です。あなたは通り過ぎます!役に立った場合は、「いいね」やブックマークをお願いします。このうち、Springコラムは一部更新中のため閲覧できませんが、ブロガーが全ての更新を完了すると閲覧できるようになります。
1. Maven シリーズの列
Maven シリーズのコラム | Maven プロジェクト開発 |
Maven 集約開発 [例の詳細な説明 --- 5555 ワード] |