开始使用AspectJ(接下来的作为了解就行)
1. [了解]@AfterThrowing 异常通知-注解中有 throwing 属性
在目标方法抛出异常后执行。该注解的 throwing 属性用于指定所发生的异常类对象。 当然,被注解为异常通知的方法可以包含一个参数 Throwable,参数名称为 throwing 指定的 名称,表示发生的异常对象。
接口:
package com.bjpowernode.ba04;
import com.bjpowernode.ba02.Student;
public interface SomeService {
void doSome(String name, Integer age);
String doOther(String name, Integer age);
Student doOther2(String name, Integer age);
String doFirst(String name, Integer age);
//这个案例中我们用这个方法
void doSecond();
}
接口的实现
package com.bjpowernode.ba04;
import com.bjpowernode.ba02.Student;
//目标类
public class SomeServiceImpl implements SomeService {
@Override
public void doSecond() {
System.out.println("执行业务方法doSecond()" + (10/0));
}
}
使用代理:
package com.bjpowernode.ba04;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import java.util.Date;
/**
* @Aspect : 是aspectj框架中的注解。
* 作用:表示当前类是切面类。
* 切面类:是用来给业务方法增加功能的类,在这个类中有切面的功能代码
* 位置:在类定义的上面
*/
@Aspect
public class MyAspect {
/**
* 异常通知方法的定义格式
* 1.public
* 2.没有返回值
* 3.方法名称自定义
* 4.方法有个一个Exception, 如果还有是JoinPoint,
*/
/**
* @AfterThrowing:异常通知
* 属性:1. value 切入点表达式
* 2. throwinng 自定义的变量,表示目标方法抛出的异常对象。
* 变量名必须和方法的参数名一样
* 特点:
* 1. 在目标方法抛出异常时执行的
* 2. 可以做异常的监控程序, 监控目标方法执行时是不是有异常。
* 如果有异常,可以发送邮件,短信进行通知
*
* 执行就是:
* try{
* SomeServiceImpl.doSecond(..)
* }catch(Exception e){
* myAfterThrowing(e);
* }
*/
@AfterThrowing(value = "execution(* *..SomeServiceImpl.doSecond(..))",
throwing = "ex")
public void myAfterThrowing(Exception ex) {
System.out.println("异常通知:方法发生异常时,执行:"+ex.getMessage());
//发送邮件,短信,通知开发人员
}
}
查看结果:
2. [了解]@After 最终通知
无论目标方法是否抛出异常,该增强均会被执行。
接口和实现:
代理对象的代码
package com.bjpowernode.ba05;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
/**
* @Aspect : 是aspectj框架中的注解。
* 作用:表示当前类是切面类。
* 切面类:是用来给业务方法增加功能的类,在这个类中有切面的功能代码
* 位置:在类定义的上面
*/
@Aspect
public class MyAspect {
/**
* 最终通知方法的定义格式
* 1.public
* 2.没有返回值
* 3.方法名称自定义
* 4.方法没有参数, 如果还有是JoinPoint,
*/
/**
* @After :最终通知
* 属性: value 切入点表达式
* 位置: 在方法的上面
* 特点:
* 1.总是会执行
* 2.在目标方法之后执行的
*
* try{
* SomeServiceImpl.doThird(..)
* }catch(Exception e){
*
* }finally{
* myAfter()
* }
*
*/
@After(value = "execution(* *..SomeServiceImpl.doThird(..))")
public void myAfter(){
System.out.println("执行最终通知,总是会被执行的代码");
//一般做资源清除工作的。
}
}
执行结果如下:
3.@Pointcut 定义切入点(比较重要)
当较多的通知增强方法使用相同的 execution 切入点表达式时,编写、维护均较为麻烦。
AspectJ 提供了@Pointcut 注解,用于定义 execution 切入点表达式。 其用法是,
将@Pointcut 注解在一个方法之上,以后所有的 execution 的 value 属性值均 可使用该方法名作为切入点。代表的就是@Pointcut 定义的切入点。这个使用@Pointcut 注解 的方法一般使用 private 的标识方法,即没有实际作用的方法。
package com.bjpowernode.ba06;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* @Aspect : 是aspectj框架中的注解。
* 作用:表示当前类是切面类。
* 切面类:是用来给业务方法增加功能的类,在这个类中有切面的功能代码
* 位置:在类定义的上面
*/
@Aspect
public class MyAspect {
@After(value = "mypt()")
public void myAfter(){
System.out.println("执行最终通知,总是会被执行的代码");
//一般做资源清除工作的。
}
@Before(value = "mypt()")
public void myBefore(){
System.out.println("前置通知,在目标方法之前先执行的");
}
/**
* @Pointcut: 定义和管理切入点, 如果你的项目中有多个切入点表达式是重复的,可以复用的。
* 可以使用@Pointcut
* 属性:value 切入点表达式
* 位置:在自定义的方法上面
* 特点:
* 当使用@Pointcut定义在一个方法的上面 ,此时这个方法的名称就是切入点表达式的别名。
* 其它的通知中,value属性就可以使用这个方法名称,代替切入点表达式了
*/
@Pointcut(value = "execution(* *..SomeServiceImpl.doThird(..))" )
private void mypt(){
//无需代码,
}
}