AOP進階樣例-基於全註解
阿新 • • 發佈:2020-07-12
配置:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion><groupId>org.example</groupId> <artifactId>aop</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.7.RELEASE</version> </dependency> </dependencies> <repositories> <repository> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>14</java.version> <maven.compiler.source>14</maven.compiler.source> <maven.compiler.target>14</maven.compiler.target> <encoding>UTF-8</encoding> </properties> </project>
程式碼:
package com.example.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @ComponentScan("com.example") @EnableAspectJAutoProxy public class Config { }
package com.example.service; /** * 賬戶的業務層介面 */ public interface IAccountService { /** * 模擬儲存賬戶 */ void saveAccount(); /** * 模擬更新賬戶 * @param i */ void updateAccount(int i); /** * 模擬銷燬賬戶 * @return */ int deleteAccount(); }
package com.example.service.impl; import com.example.service.IAccountService; import org.springframework.stereotype.Service; /** * 賬戶的業務層實現類 */ @Service("accountService") public class AccountServiceImpl implements IAccountService { @Override public void saveAccount() { System.out.println("執行了儲存"); } @Override public void updateAccount(int i) { System.out.println("執行了更新:"+i); } @Override public int deleteAccount() { System.out.println("執行了刪除"); return 0; } }
package com.example.utils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * 用於記錄日誌的工具類,它裡面提供了公共程式碼 */ @Component("logger") @Aspect public class Logger { @Pointcut("execution(* com.example.service.impl.*.*(..))") private void pt1(){} /** * 前置通知 befor */ @Before("pt1()") public void beforePrintLog(){ System.out.println("Logger.beforePrintLog"); } /** * 後置通知 after */ @AfterReturning("pt1()") public void afterReturningPrintLog(){ System.out.println("Logger.afterReturningPrintLog"); } /** * 異常通知 throw */ @AfterThrowing("pt1()") public void afterThrowingPrintLog(){ System.out.println("Logger.afterThrowingPrintLog"); } /** * 最終通知 finally */ @After("pt1()") public void afterPrintLog(){ System.out.println("Logger.afterPrintLog"); } /** * 環繞通知:用於增強方法(pjp) * 問題:切入點方法未執行,通知方法在執行了 * 解決:需要pjp.proceed方法顯示呼叫切入點方法 */ @Around("pt1()") public Object aroundPrintLog(ProceedingJoinPoint pjp){ System.out.println("Logger.aroundPrintLog"); Object rtValue=null; Object[] args = pjp.getArgs(); try { //前置 rtValue=pjp.proceed(args); //後置 } catch (Throwable throwable) { //異常 throw new RuntimeException(throwable); }finally { //最終 } return rtValue; } }
測試:
package com.example.service; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = com.example.config.Config.class) public class AccountServiceTest { @Autowired IAccountService service; @Test public void testSaveAccount(){ service.saveAccount(); service.updateAccount(0); service.deleteAccount(); } }