SpringAop (一)

要在 Spring 应用中使用 AspectJ 注解, 必须在 classpath 下包含 AspectJ 类库:
aopalliance.jar、aspectj.weaver.jar 和 spring-aspects.jar
将 aop Schema 添加到
<beans> 根元素中. 要在 Spring IOC 容器中启用 AspectJ 注解支持, 只要在 Bean 配置文件中定义一个空的 XML 元素 <aop:aspectj-autoproxy>
当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时,会自动为与 AspectJ 切面匹配的 Bean 创建代理要在 Spring 中声明 AspectJ 切面,
只需要在 IOC 容器中将切面声明为 Bean 实例. 当在 Spring IOC 容器中初始化 AspectJ 切面之后,Spring IOC 容器就会为那些与 AspectJ 切面相匹配的 Bean 创建代理.
在 AspectJ 注解中, 切面只是一个带有 @Aspect 注解的 Java 类. 通知是标注有某种注解的简单的 Java 方法. AspectJ 支持 5 种类型的通知注解: @Before: 前置通知, 在方法执行之前执行 @After: 后置通知, 在方法执行之后执行 @AfterRunning: 返回通知, 在方法返回结果之后执行 @AfterThrowing: 异常通知, 在方法抛出异常之后 @Around: 环绕通知, 围绕着方法执行

xml

<?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/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

    <context:component-scan base-package="com.aspectsAop"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

 

前置、后置、返回、异常AOP处理

 1 package com.aspectsAop;
 2 
 3 import java.util.Arrays;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 import org.aspectj.lang.annotation.Around;
 6 import org.aspectj.lang.annotation.Aspect;
 7 import org.aspectj.lang.annotation.Pointcut;
 8 import org.springframework.core.annotation.Order;
 9 import org.springframework.stereotype.Component;
10 
11 /**
12  * 可以使用 @Order 注解指定切面的优先级, 值越小优先级越高
13  */
14 @Order(1)
15 @Aspect
16 @Component
17 public class ArithmeticCalculatorAspectsAround {
18 
19     /**
20      * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码. 
21      * 使用 @Pointcut 来声明切入点表达式. 
22      * 后面的其他通知直接使用方法名来引用当前的切入点表达式. 
23      */
24     @Pointcut("execution(public int com.aspectsAop.ari.ArithmeticCalculatorImpl.*(..))")
25     public void declareJointPointExpression() {
26 
27     }
28 
29     /**
30      * 环绕通知需要携带 ProceedingJoinPoint 类型的参数. 
31      * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.
32      * 且环绕通知必须有返回值, 返回值即为目标方法的返回值
33      */
34     /**
35      * 在 ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码
36      */
37     @Around(value = "declareJointPointExpression()")
38     public Object aroundMethods(ProceedingJoinPoint point) {
39 
40         Object result = null;
41         Object args = point.getArgs();
42         String methodName = point.getSignature().getName();
43         try {
44             // 1.前置通知
45             System.out.println("环绕前置通知信息Method:" + methodName + "<参数>==》" + Arrays.asList(args));
46             // 2.执行目标方法
47             result = point.proceed();
48             // 3.返回通知
49             System.out.println("环绕后置通知信息Method:" + methodName + "<参数>==》" + Arrays.asList(args) + "》》结果:" + result);
50         } catch (Throwable e) {
51             // 4.异常通知
52             System.out.println("环绕后置通知信息Method:" + methodName + "<参数>==》" + Arrays.asList(args) + "异常信息:" + e);
53             throw new RuntimeException(e);
54         }
55         // 5.方法完成后的返回通知
56         System.out.println("环绕方法执行完成通知信息Method:" + methodName + "<参数>==》" + Arrays.asList(args));
57         return result;
58     }
59 }

 

posted @ 2019-07-10 16:31  smokerBig  阅读(227)  评论(0编辑  收藏  举报