Spring-註解的方式配置AOP-案例
阿新 • • 發佈:2019-02-19
需求:分別在AtithmeticCalculator.java實現了該介面的類的加減乘除的方法執行時列印方法執行情況,並在方法執行前判斷所有引數是否都是int,用aop實現。
介面實現類:AtithmeticCalculatorImpl.java
第一個切面類:VlidationAspect.java實現判斷請求的引數是不是int/* * 檔名:AtithmeticCalculatorImpl.java * 版權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-11-2 * 跟蹤單號: * 修改單號: * 修改內容: */ package com.cgc.spring.aop.impl; import org.springframework.stereotype.Component; /** * <一句話功能簡述> <功能詳細描述> * * @author 姓名 工號 * @version [版本號, 2015-11-2] * @see [相關類/方法] * @since [產品/模組版本] */ @Component public class AtithmeticCalculatorImpl implements AtithmeticCalculator { /** * 過載方法 * * @param i * @param j * @return */ @Override public int add(int i, int j) { int result = i + j; return result; } /** * 過載方法 * * @param i * @param j * @return */ @Override public int sub(int i, int j) { int result = i - j; return result; } /** * 過載方法 * * @param i * @param j * @return */ @Override public int mul(int i, int j) { int result = i * j; return result; } /** * 過載方法 * * @param i * @param j * @return */ @Override public int div(int i, int j) { int result = 0; try { //前置通知 result = i / j; //返回通知 } catch (Exception e) { e.printStackTrace(); //異常通知,可以訪問到出現的異常 } //後置通知,因為方法可能會出現異常,所以訪問不到方法的返回值 return result; } }
第二個切面類:在不同方法執行前,列印不同方法的執行日誌:LoggingAspect.java/* * 檔名:VlidationAspect.java * 版權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-11-2 * 跟蹤單號: * 修改單號: * 修改內容: */ package com.cgc.spring.aop.impl; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * <一句話功能簡述> * <功能詳細描述> * * @author 姓名 工號 * @version [版本號, 2015-11-2] * @see [相關類/方法] * @since [產品/模組版本] */ //@Order(1)設定切面的優先順序 值越小 優先順序越高 @Order(1) @Aspect @Component public class VlidationAspect { //不同的包下要加包名 com.cgc.spring.aop.impl.LoggingAspect.declareJointPointExpression() @Before("LoggingAspect.declareJointPointExpression()") public void validateArrgs(JoinPoint joinPoint) { System.out.println("-->validate"+Arrays.asList(joinPoint.getArgs())); //可以在此處實現請求的引數是不是int型別,從joinPoint中可以獲取請求的引數 } }
配置檔案:applicationContext.xml/* * 檔名:LoggingAspect.java * 版權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-11-2 * 跟蹤單號: * 修改單號: * 修改內容: */ package com.cgc.spring.aop.impl; import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * <一句話功能簡述> * <功能詳細描述> * * @author 姓名 工號 * @version [版本號, 2015-11-2] * @see [相關類/方法] * @since [產品/模組版本] */ //把一個類宣告為一個切面:需要把該類放入到IOC容器中,再宣告為一個切面 @Order(2) @Aspect @Component public class LoggingAspect { //定義一個方法,用於宣告切入點表示式,一般的 該方法中不需要再新增其他程式碼 @Pointcut("execution(public int com.cgc.spring.aop.impl.AtithmeticCalculatorImpl.*(..) )") public void declareJointPointExpression() { } //宣告該方法是一個前置通知,在目標方法開始之前執行.第一個*表示任意修飾符 任意返回值,後邊的*表示任意方法名 //@Before("execution(* com.cgc.spring.aop.impl.AtithmeticCalculatorImpl.*(int, int) )") @Before("declareJointPointExpression()") public void beforeMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("this is method "+methodName +" begin with "+ args); } //後置通知:在目標方法執行後(無論是否發生異常),執行的通知 //在後置通知中不能訪問在目標方法中返回的執行結果 @After("execution(public int com.cgc.spring.aop.impl.AtithmeticCalculatorImpl.*(int, int) )") public void afterMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("this is method "+methodName +" end with "); } //在方法正常結束後要執行的程式碼 //返回通知是可以訪問到方法的返回值的 @AfterReturning(value="declareJointPointExpression()",returning="result") public void afterReturning(JoinPoint joinPoint,Object result) { String methodName = joinPoint.getSignature().getName(); System.out.println("this is method "+methodName +" after Returning " + result); } //在方法出現異常時,會執行的程式碼,而且可以訪問到異常物件,且可以指定在出現 特定異常時在執行通知程式碼 Exception ex,NullPointerException ex @AfterThrowing(value="declareJointPointExpression())",throwing="ex") public void afterThrowing(JoinPoint joinPoint , Exception ex) { String methodName = joinPoint.getSignature().getName(); System.out.println("this is method "+methodName +" after Returning exception " + ex); } }
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置自動掃描的包 -->
<context:component-scan base-package="com.cgc.spring.aop.impl"></context:component-scan>
<!-- 使Aspject 註解其作用:自動為匹配的類生成代理物件 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
通過main呼叫方法:
public static void main(String[] args)
{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
AtithmeticCalculator cal = ac.getBean(AtithmeticCalculator.class);
System.out.println(cal.getClass().getName());
int result = cal.add(3, 4);
System.out.println(result);
int result00 = cal.div(10, 2);
System.out.println(result00);
}