AOP的通知类型
Aop的通知类型,主要是定义通知方法的触发时机。主要包括:
1) 前置通知:before 在连接点方法执行之前执行。
<aop:before method="before" pointcut-ref="timePointcut"></aop:before>
2) 后置通知:after 在连接点方法执行之后,无论如何都会执行。(finally)
method:指定切面中的通知方法, pointcut-ref:指定切入点 <aop:after method="after" pointcut-ref="timePointcut"></aop:after>
3) 环绕通知:around 在连接点方法执行之前和之后执行。(拦截器)
<aop:around method="around" pointcut-ref="timePointcut"></aop:around>
4) 异常通知:after-throwing 在连接点方法发生异常之后执行。
throwing:关联到方法异常参数 <aop:after-throwing method="afterThrowing" throwing="e" pointcut-ref="timePointcut"></aop:after-throwing>
5) 返回通知:after-returning 在连接点方法返回结果后执行(如果发生异常则不会执行)。
returning:指定返回结果参数 <aop:after-returning method="afterReturning" pointcut-ref="timePointcut" returning="result"></aop:after-returning>
可以看一下下面的这个表,相信你会更加熟悉的;
Try{
前置通知 before
环绕通知 around 前半部分
调用连接点方法
环绕通知 around 后半部分
返回通知 after-returning
}cathc(Exception e){
异常通知after-throwing
} finally{
after 后置通知
}
注解配置AOP:
1) 在spring配置文件中设置开启注解配置。<aop:aspectj-autoproxy/>
<!-- 声明开启AOP注解--> <aop:aspectj-autoproxy/>
2) 在切面类上添加@Aspect注解 标识为切面类。
@Aspect //切面注解 public class TimeAspect { }
3) 定义一个空方法,在方法上面添加@Piontcut注解定义切入点
//定义一个空方法,来申明切入点 //类似于在XML定义 <aop:pointcut> </aop:pointcut> @Pointcut("execution(* aop.StudentAction.*(..))") public void declarePointcut(){
}
4) 在对应的通知上面添加对应的通知类型注解
a. @Before;
//通知方法==>方法==>切入的业务逻辑 //joinPoint:连接点对象,可以获取连接点的一些基本信息 //Before:指定为前置通知(声明的切入点方法) @Before("declarePointcut()") public void before(JoinPoint joinPoint){ //获取连接点方法的参数 Object[] args=joinPoint.getArgs(); System.out.println(Arrays.toString(args)); //getSignature:获取连接点方法结构 getName:获取连接点方法名 String name=joinPoint.getSignature().getName(); System.out.println(name); //获取目标类 Object target=joinPoint.getTarget(); System.out.println(target); System.out.println("开始执行"+target+"类的"+name+"方法,参数列表为:"+Arrays.toString(args)); System.out.println("开始时间:"+System.currentTimeMillis()); }
b. @After;
@After("declarePointcut()") public void after(){ System.out.println("结束时间:"+System.currentTimeMillis()); }
c. @Around
//环绕通知 @Around("declarePointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知前半部分处理==========="); //执行连接点方法,并获取返回值 Object result=joinPoint.proceed(); System.out.println("环绕通知后半部分处理,获取到返回值:"+result); //返回结果,此处可改变方法的返回结果 return result; }
d. @After-Throwing;
//异常通知 e:发生的异常 @AfterThrowing(value = "declarePointcut()",throwing = "e") public void afterThrowing(Exception e){ System.out.println("进入异常通知"); e.printStackTrace(); }
e. @After-Returning;
//返回通知 result:连接点方法的返回值 @AfterReturning(value = "declarePointcut()" ,returning = "result") public void afterReturning(Object result){ System.out.println("返回通知,获取到方法返回值:"+result); }
它的测试文件为:
@Controller public class StudentAction { @Autowired private StudentService studentService; public int delete(Integer id,String name){ return studentService.delete(); } public void insert(){ int i=1/0; studentService.insert(); } public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext2.xml"); StudentAction studentAction = (StudentAction) applicationContext.getBean("studentAction"); studentAction.delete(1,"王大锤"); System.out.println("==================================================================="); studentAction.insert(); } }