1.AspectJ 注解声明切面
1.1 AspectJ 支持 5 种类型的通知注解
@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行
@AfterRunning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around: 环绕通知, 围绕着方法执行
@Aspect
@Component
public class LoggingAspect {
//前置通知,在方法执行之前执行
@Before("execution(* bean.Calculator.*(int, int))")
public void beforeMethod(JoinPoint joinPoint){
String methodName =joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("The Method"+ methodName + "begin with"+args);
}
//后置通知, 在方法执行之后执行
@After("execution(* bean.Calculator.*(int, int))")
public void afterMethod(JoinPoint joinPoint){
String methodName =joinPoint.getSignature().getName();
System.out.println("The Method"+ methodName + "ends");
}
//返回通知, 在方法返回结果之后执行
@AfterReturning(value = "execution(* bean.Calculator.*(int, int))",returning = "result")
public void afterReturning(JoinPoint joinPoint,Object result){
String methodName =joinPoint.getSignature().getName();
System.out.println("The Method"+ methodName + "end with "+result);
}
//异常通知, 在方法抛出异常之后
@AfterThrowing(value = "execution(* bean.Calculator.*(int, int))",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
String methodName =joinPoint.getSignature().getName();
System.out.println("The Method"+ methodName + " occurs excetion:" + e);
}
//环绕通知, 围绕着方法执行
@Around("execution(* bean.Calculator.*(int, int))")
public Object aroundMethod(ProceedingJoinPoint pjp){
Object result = null;
String methodName =pjp.getSignature().getName();
try {
//前置通知
System.out.println("The Method"+ methodName + "-->"+Arrays.asList(pjp.getArgs()));
//执行目标方法
result = pjp.proceed();
//返回通知
System.out.println("The method " + methodName + "-->" + result);
} catch (Throwable e) {
//异常通知
System.out.println("The method " + methodName + "-->" + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + "<--");
return result;
}
}
1.2 @Order():指定切面优先级,数字越小优先级越高
@Order(1)
@Aspect
@Component
public class LoggingAspect {...}
1.3 @Pointcut:声明切入表达式
//定义一个方法,用来声明切入表达式
//使用@Pointcut声明切入表达式
@Pointcut("execution(* bean.Calculator.*(int, int))")
public void expression(){}
//直接使用方法名引入当前的切入点表达式
@Before("expression()")
public void beforeMethod(JoinPoint joinPoint){...}
2.用基于 XML 的配置声明切面
(1) 配置Bean
(2) 配置切面Bean
(3) 配置AOP(配置切点表达式、配置切面及通知)
VerificationAspect:验证作用的切面
public class VerificationAspect {
public void beforeMehtod(JoinPoint joinPoint){...}
}
application.xml
<!-- 配置 bean -->
<bean id="calculator" class="bean.CalculatorImpl"></bean>
<!-- 配置切面的 bean. -->
<bean id="Verification" class="bean.VerificationAspect"></bean>
<!-- 配置 AOP -->
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut id="point" expression="execution(* bean.Calculator.*(int, int))"/>
<!-- 配置切面及通知 -->
<aop:aspect ref="Verification" order="1">
<aop:before method="beforeMehtod" pointcut-ref="point"/>
</aop:aspect>
</aop:config>