AOP也就是咱們平常說的@面向切面編程,看概念比較晦澀難懂,難懂的是設計理念,以及這樣設計的好處是什麼。在Spring的AOP中,經常使用的幾個註解以下:@Aspect,@Before,@After,@AfterReturning,@AfterThrowing,@Around,@PointCut以及@EnableAspectJAutoProxyspring
1. 模擬業務類CalculateService編程
/** * description:模擬業務類 * * @author 70KG * @date 2018/12/17 */ public class CalculateService { public int calculate(int i, int j) { int result = i / j; System.out.println("---->CalculateService-業務方法執行。。。。。。"); return result; } }
2. 編寫切面類,切面類必須標註它爲切面類(@Aspect),關於切入點表達式,能夠參考官方文檔,寫法不少種,還有關於JoinPoint這個參數必須放在第一位,不然報錯。測試
/** * description:日誌切面類,JoinPoint必須在參數的第一位 * * @author 70KG * @date 2018/12/17 */ @Aspect // ---> 聲明此類是一個切面類 public class LogAdvice { @Pointcut("execution(* com.nmys.story.springCore.springaop.sample01.CalculateService.*(..))") public void pointCut() { } /** * 目標方法執行前執行 */ @Before("pointCut()") public void logBefore(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); Object[] args = joinPoint.getArgs(); System.out.println("---->" + signature + "方法執行前,傳入的參數是:" + Arrays.asList(args)); } /** * 目標方法執行後執行 */ @After("pointCut()") public void logAfter(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); Object[] args = joinPoint.getArgs(); System.out.println("---->" + signature + "方法執行後,傳入的參數是:" + Arrays.asList(args)); } /** * 方法發生異常時執行 */ @AfterThrowing(value = "pointCut()", throwing = "ex") public void logException(JoinPoint joinPoint, Exception ex) { Signature signature = joinPoint.getSignature(); System.out.println("---->" + signature + "方法執行後,拋出了異常信息:" + ex.getMessage()); } /** * 正常返回時執行 */ @AfterReturning(value = "pointCut()", returning = "result") public void logReturn(JoinPoint joinPoint, Object result) { Signature signature = joinPoint.getSignature(); System.out.println("---->" + signature + "方法執行後,返回的結果是:" + result); } }
3. 配置類spa
/** * description * * @author 70KG * @date 2018/12/17 */ @Configuration @EnableAspectJAutoProxy // ---> 開啓切面的自動代理 public class MyConfig { @Bean public CalculateService calculateService() { return new CalculateService(); } // 將切面類也交給容器管理 @Bean public LogAdvice logAdvice() { return new LogAdvice(); } }
4. 測試類設計
/** * description * * @author 70KG * @date 2018/12/17 */ public class Test01 { public static void main(String[] args) { // 加載配置文件 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class); CalculateService calc = (CalculateService) ac.getBean("calculateService"); calc.calculate(4,2); } }
5. 結果代理
---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行前,傳入的參數是:[4, 2] ---->CalculateService-業務方法執行。。。。。。 ---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行後,傳入的參數是:[4, 2] ---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行後,返回的結果是:2