3.6 AspectJ 对 AOP的实现(重点)
3.6.1 简介
AspectJ 是一个面向切面的框架,它扩展了java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
3.6.1 AspectJ基于注解的AOP实现
package com.bjpowernode.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect // 表示当前类为切面
public class MyAspect {
@Before("execution(* *..ISomeService.doFirst(..))")
public void myBefore() {
System.out.println("执行前置通知方法");
}
@Before("execution(* *..ISomeService.doFirst(..))")
public void myBefore(JoinPoint jp) {
System.out.println("执行前置通知方法 jp = " + jp);
}
@AfterReturning("execution(* *..ISomeService.doSecond(..))")
public void myAfterReturning() {
System.out.println("执行后置通知方法");
}
@AfterReturning(value="execution(* *..ISomeService.doSecond(..))", returning="result")
public void myAfterReturning(Object result) {
System.out.println("执行后置通知方法 result = " + result);
}
@Around("execution(* *..ISomeService.doSecond(..))")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行环绕通知方法,目标方法执行之前");
// 执行目标方法
Object result = pjp.proceed();
System.out.println("执行环绕通知方法,目标方法执行之后");
if(result != null) {
result = ((String)result).toUpperCase();
}
return result;
}
@AfterThrowing("execution(* *..ISomeService.doThird(..))")
public void myAfterThrowing() {
System.out.println("执行异常通知方法");
}
@AfterThrowing(value="doThirdPointcut()", throwing="ex")
public void myAfterThrowing(Exception ex) {
System.out.println("执行异常通知方法 ex = " + ex.getMessage());
}
@After("doThirdPointcut()")
public void myAfter() {
System.out.println("执行最终通知方法");
}
// 定义了一个切入点,叫 doThirdPointcut()
@Pointcut("execution(* *..ISomeService.doThird(..))")
public void doThirdPointcut(){}
@Pointcut("execution(* *..ISomeService.doSecond(..))")
public void doSecondPointcut(){}
}
3.6.2 AspectJ基于XML的AOP实现
(1)前置
<?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" 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.xsd">
<!-- 注册切面 -->
<bean id="myAspect" class="com.bjpowernode.xml.MyAspect"/>
<!-- 注册目标对象 -->
<bean id="someService" class="com.bjpowernode.xml.SomeServiceImpl"/>
<!--aop配置 -->
<aop:config>
<aop:pointcut expression="execution(* *..ISomeService.doFirst(..))" id="doFirstPointCut"/>
<aop:pointcut expression="execution(* *..ISomeService.doSecond(..))" id="doSecondPointCut"/>
<aop:pointcut expression="execution(* *..ISomeService.doThird(..))" id="doThirdPointCut"/>
<aop:aspect ref="myAspect">
<!-- 前置通知 -->
<aop:before method="myBefore" pointcut-ref="doFirstPointCut"/>
<aop:before method="myBefore(org.aspectj.lang.JoinPoint)" pointcut-ref="doSecondPointCut"/>
</aop:aspect>
</aop:config>
</beans>
(2)后置
<aop:after-returning method="myAfterReturning" pointcut-ref="doSecondPointCut"/>
<aop:after-returning method="myAfterReturning(java.lang.Object)" pointcut-ref="doSecondPointCut" returning="result"/>
returning="result" 指定参数名称
(3)环绕
<aop:around method="myAround" pointcut-ref="doThirdPointCut"/>
(4)异常
<aop:after-throwing method="myAfterThrowing" pointcut-ref="doThirdPointCut"/>
<aop:after-throwing method="myAfterThrowing(java.lang.Exception)" pointcut-ref="doThirdPointCut" throwing="ex"/>
throwing="ex" 指定参数名称
(5)指定最终通知
<aop:after method="myAfter" pointcut-ref="doThirdPointCut"/>