Spring--9.aop操作

来源:互联网 发布:淘宝网孕妇秋装套装 编辑:程序博客网 时间:2024/06/11 22:24

1       概述

1.1  aspectj

1 在spring里面进行aop操作,使用aspectj实现

(1)aspectj不是spring一部分,和spring一起使用进行aop操作

(2)Spring2.0以后新增了对AspectJ支持

 

1.2  两种方式

2 使用aspectj实现aop有两种方式(重点)

(1)基于aspectj的xml配置

(2)基于aspectj的注解方式

 

 

 

2       Aop操作准备—aspect

2.1  导包

1 除了导入基本的jar包之外,还需要导入aop相关的jar包

 

2.2  引入约束

2 创建spring核心配置文件,导入aop的约束

 

 

3       增强类

          被加强的方法所在的类叫被增强类

 

3.1  切入点表达式

1 切入点:实际增强的方法

 

2 常用的表达式

execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

(1)execution(*  spring.aop.Book.add(..))

(2)execution(* spring.aop.Book.*(..))

(3)execution(* *.*(..))

(4) 匹配所有save开头的方法 execution(* save*(..))

 

3. 切入点表达式操作符 &&, ||, !

 

       在 AspectJ 切面中, 可以通过 @Pointcut 注解将一个切入点声明成简单的方法. 切入点的方法体通常是空的

 

3.2  五种通知

 

3.2.1   前置通知-- JoinPoint访问连接点

       前置通知:在方法执行之前执行的通知;   前置通知使用 @Before 注解, 并将切入点表达式的值作为注解值.

       可以在通知方法中声明一个类型为 JoinPoint 的参数. 然后就能访问链接细节. 如方法名称和参数值.

//声明该方法是一个前置通知:在目标方法开始前执行    @Before("execution(publicint spring.aop.impl.*.*(int , int))")    public void beforeMethod(JoinPoint joinPoint){       String methodName = joinPoint.getSignature().getName();       List<Object> args = Arrays.asList(joinPoint.getArgs());             System.out.println("此方法 "+ methodName +" 开始:" + args);    }

3.2.2   后置通知-- JoinPoint

       后置通知是在连接点完成之后执行的, 即连接点返回结果或者抛出异常的时候, 下面的后置通知记录了方法的终止.

       一个切面可以包括一个或者多个通知.

//后置通知:在目标方法开始后执行(无论是否发生异常),其不能访问控制结果    @After("execution(publicint spring.aop.impl.*.*(int , int))")    public void afterMethod(JoinPoint joinPoint){       String methodName = joinPoint.getSignature().getName();                 System.out.println("此方法 "+ methodName +" 结束");    } 

3.2.3   返回通知—JoinPoint,result访问连接点的返回值

       在返回通知中, 只要将 returning 属性添加到 @AfterReturning 注解中, 就可以访问连接点的返回值. 该属性的值即为用来传入返回值的参数名称.

       必须在通知方法的签名中添加一个同名参数. 在运行时, Spring AOP 会通过这个参数传递返回值.

       原始的切点表达式需要出现在 pointcut 属性中

//返回通知:在目标方法开始后执行,是可以访问到方法的返回值的    @AfterReturning(value = "execution(publicint spring.aop.impl.*.*(int , int))" ,    returning = "result")    public void afterReturning(JoinPoint joinPoint , Object result){       String methodName = joinPoint.getSignature().getName();                    System.out.println("此方法 "+ methodName +" 结果: " + result);    }  

3.2.4   异常通知—JoinPoint,Exception

       只在连接点抛出异常时才执行异常通知

       将 throwing 属性添加到 @AfterThrowing 注解中, 也可以访问连接点抛出的异常. Throwable 是所有错误和异常类的超类. 所以在异常通知方法可以捕获到任何错误和异常.

//异常通知:在目标方法异常后执行;是可以访问到  异常对象    @AfterThrowing(value = "execution(publicint spring.aop.impl.*.*(int , int))" ,throwing = "e")    public void afterThrowing(JoinPoint joinPoint , Exception e){       String methodName = joinPoint.getSignature().getName();                        System.out.println("此方法 "+ methodName +" 异常: " + e);    }   

3.2.5   环绕通知—ProceedingJoinPoint连接点

       环绕通知相当于前面四种的一个概括

对于环绕通知来说, 连接点的参数类型必须是 ProceedingJoinPoint ,其中proceed() 方法来执行被代理的方法. 如果忘记这样做就会导致通知被执行了, 但目标方法没有被执行.

       注意: 环绕通知的方法需要返回目标方法执行之后的结果, 即调用 joinPoint.proceed(); 的返回值, 否则会出现空指针异常

//把这个类声明为一个对象:需要把该类放入 IOC 容器中,再声明一个切面@Aspect@Componentpublic class Logging {    /**     * 环绕通知:相当于前四种通知的集合     * 需要携带ProceedingJoinPoint 类型参数     * 类似动态代理的全过程,ProceedingJoinPoint类型参数可以决定是否执行目标方法,且要有返回值     */    @Around("execution(publicint spring.aop.impl.*.*(int , int))")    public Object aroundMethod(ProceedingJoinPoint pjp){       Object result = null;             String methodName = pjp.getSignature().getName();       List<Object> args = Arrays.asList(pjp.getArgs());             try {           //前置通知           System.out.println("前置通知此方法 "+ methodName +" 开始:" + args);           //执行方法           result = pjp.proceed();           //返回通知           System.out.println("返回通知此方法 "+ methodName +" 结果: " + result);       } catch (Throwable e) {           //异常通知           System.out.println("异常通知此方法 "+ methodName +" 异常: " + e);           throw new RuntimeException(e);       }       //后置通知       System.out.println("后置通知此方法 "+ methodName +" 结束");       return result;    }} 

3.3  切面优先级

  

4       Aspectj的aop操作(xml配置)

4.1  增强类

 

4.2  XML配置

4.2.1   配置

  

4.2.2   配置切入点

切入点使用<aop:pointcut> 元素声明

切入点必须定义在 <aop:aspect> 元素下, 或者直接定义在<aop:config> 元素下.

定义在 <aop:aspect> 元素下: 只对当前切面有效

定义在 <aop:config> 元素下: 对所有切面都有效

基于 XML 的 AOP 配置不允许在切入点表达式中用名称引用其他切入点.

 

4.2.3   配置切面—引入增强对象

       当使用 XML 声明切面时, 需要在 <beans> 根元素中导入 aop Schema

       在 Bean 配置文件中, 所有的 Spring AOP 配置都必须定义在 <aop:config> 元素内部. 对于每个切面而言, 都要创建一个<aop:aspect> 元素来为具体的切面实现引用后端 Bean 实例.

       切面 Bean 必须有一个标示符, 供 <aop:aspect> 元素引用

4.2.4   配置通知—引入切入点

       在 aop Schema 中, 每种通知类型都对应一个特定的 XML 元素.

       通知元素需要使用 <pointcut-ref> 来引用切入点, 或用 <pointcut> 直接嵌入切入点表达式.  method 属性指定切面类中通知方法的名称.

 

<!-- 1.创建对象 -->   <bean id="book" class="spring.aop.Book"></bean>   <bean id="myBook" class="spring.aop.MyBook"></bean>     <!-- 2.配置aop操作 -->   <aop:config>      <!-- 2.1配置切入点 -->      <aop:pointcut expression="execution(* spring.aop.Book.*(..))"id="pointcut1"/>      <!-- 2.2配置切面  把增强用到方法上面-->      <aop:aspect ref="myBook">         <!-- 配置增强类型  method:增强类里面使用哪个方法作为前置-->         <aop:before method="before1" pointcut-ref="pointcut1"/>         <aop:after-returning method="after1" pointcut-ref="pointcut1"/>                 <aop:around method="around1" pointcut-ref="pointcut1"/>      </aop:aspect>   </aop:config> 

5       aop操作(注解)

5.1  XML

第一步 创建对象

第二步 在spring核心配置文件中,开启aop操作

 

 

5.2  增强类注解

第三步 在增强类上面使用注解完成aop操作

 

原创粉丝点击