zoukankan      html  css  js  c++  java
  • Spring AOP前置通知和后置通知

    Spring AOP
      AspectJ:Java社区里最完整最流行的AOP框架
      在Spring2.0以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP


    在Spring中启用AspectJ注解支持
      要在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创建代理


    用AspectJ注解声明切面
      要在Spring中声明AspectJ切面,只需要在IOC容器中将切面声明为bean实例。当在Spring IOC容器中初始化AspectJ切面之后,Spring IOC容器就会为那些与AspectJ切面相匹配的bean创建代理
      在AspectJ注解中,切面只是一个带有@AspectJ注解的Java类
      通知是标注有某种注解的简单的Java方法
      AspectJ支持5种类型的通知注解:
        @Before:前置通知,在方法执行之前返回
        @After:后置通知,在方法执行后执行
        @AfterRunning:返回通知,在方法返回结果之后执行
        @AfterThrowing:异常通知,在方法抛出异常之后
        @Around:环绕通知,围绕着方法执行

    利用方法签名编写AspectJ切入点表达式
      最典型的切入点表达式时根据方法的签名来匹配各种方法:
        -execution * com.yl.spring.aop.ArithmeticCalculator.*(..):匹配ArithmeticCalculator中声明的所有方法,第一个*代表任意修饰符及任意返回值,第二个*代表任意方法,..匹配任意数量的参数。若目标类与接口与切面在同一个包中,可以省略包名。
        -execution public * ArithmeticCalculator.*(..):匹配ArithmeticCalculator接口的所有公有方法
        -execution public double ArithmeticCalculator.*(..):匹配ArithmeticCalculator中返回double类型数值的方法
        -execution public double ArithmeticCalculator.*(double, ..):匹配第一个参数为double类型的方法,..匹配任意数量任意类型的参数
        -execution public double ArithmeticCalculator.*(double, double):匹配参数类型为double,double类型的方法

    后置通知
      后置通知是在连接点完成之后执行的,即连接点返回结果或者抛出异常的时候,下面的后置通知记录了方法的终止。
      一个切面可以包括一个或者多个通知

    LoggingAspect.java

     1 package com.yl.spring.aop.impl;
     2 
     3 import java.util.Arrays;
     4 import java.util.List;
     5 
     6 import org.aspectj.lang.JoinPoint;
     7 import org.aspectj.lang.annotation.After;
     8 import org.aspectj.lang.annotation.Aspect;
     9 import org.aspectj.lang.annotation.Before;
    10 import org.springframework.stereotype.Component;
    11 
    12 //这个类声明为一个切面:需要把该类放入到IOC容器中;再声明为一个切面
    13 @Aspect
    14 @Component
    15 public class LoggingAspect {
    16     
    17     //声明该方法是一个前置通知:在目标方法开始之前执行
    18     //@Before("execution(public int com.yl.spring.aop.impl.ArithmeticCalculatorImpl.add(int, int))")
    19     @Before("execution(* com.yl.spring.aop.impl.*.*(..))")
    20     public void beforeMethod(JoinPoint joinpoint) {
    21         String methodName = joinpoint.getSignature().getName();
    22         List<Object> args = Arrays.asList(joinpoint.getArgs());
    23         System.out.println("The method " + methodName + " begins with " + args);
    24     }
    25     //后置通知:在目标方法执行后(无论是否发生异常),执行的通知
    26     //在后置通知中,还不能访问目标方法执行的结果
    27     @After("execution(* com.yl.spring.aop.impl.*.*(..))")
    28     public void afterMethod(JoinPoint joinPoint) {
    29         String methodName = joinPoint.getSignature().getName();
    30         List<Object> args = Arrays.asList(joinPoint.getArgs());
    31         System.out.println("The method " + methodName + " end with " + args);
    32     }
    33     
    34 }

    配置文件applicationContext.xml:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:aop="http://www.springframework.org/schema/aop"
     5     xmlns:context="http://www.springframework.org/schema/context"
     6     xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
     7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
     9     
    10     <!-- 配置自动扫描的包 -->
    11     <context:component-scan base-package="com.yl.spring.aop.impl"></context:component-scan>
    12     
    13     <!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
    14     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    15     
    16 </beans>

    测试类:

     1 package com.yl.spring.aop.impl;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class Main {
     7     public static void main(String[] args) {
     8         
     9         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    10         
    11         ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
    12         
    13         int result = arithmeticCalculator.add(4, 6);
    14         System.out.println("result: " + result);
    15         
    16         result = arithmeticCalculator.mul(4, 6);
    17         System.out.println("result: " + result);
    18     } 
    19 }
  • 相关阅读:
    Arduino学习笔记 (五) -- 红外接收与解码
    Arduino学习笔记 (四) -- 常用函数
    VSCode 基础必备插件
    Arduino学习笔记 (三) -- 语言基本概念
    Arduino学习笔记 (二) -- 常见板型
    Arduino学习笔记 (一) -- 概述
    一个好玩的东西:页面点击鼠标左键显示浮动文字
    Python多线程
    Nginx配置转发
    阿里云(CentOs)搭建SVN服务
  • 原文地址:https://www.cnblogs.com/dreamfree/p/4095858.html
Copyright © 2011-2022 走看看