20Spring切面的优先级

通过使用@order注解指定切面的优先级,值越小,优先级越高代码:
package com.cn.spring.aop.impl;
//加减乘除的接口类
public interface ArithmeticCalculator {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}


package com.cn.spring.aop.impl;

import org.springframework.stereotype.Component;

//实现类
@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        return result;
    }

    @Override
    public int sub(int i, int j) {
        int result = i - j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result = i * j;
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        return result;
    }
}
package com.cn.spring.aop.impl;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

//把这个类声明为一个切面:首先需要把该类放入到IOC容器中,在声明为一个切面
//可以使用@order注解指定切面的优先级,值越小,优先级越高
@Order(2)
@Aspect
@Component
public class LoggingAspect {

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

        System.out.println("The method " +  methodName + " begins with " + args);
    }

    //后置通知:在目标方法执行后(无论是否发生异常),执行的通知
    //在后置通知中还不能访问目标方法执行的结果
    @After("execution(public int ArithmeticCalculator.*(int, int))")
    public void afterMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        List<Object> args = Arrays.asList(joinPoint.getArgs());

        System.out.println("The method " +  methodName + " ends with " + args);
    }

    /**
     * 在方法正常结束后执行的代码
     * 返回通知是可以访问到方法的返回值
     * @param joinPoint
     */
    @AfterReturning(value = "execution(public int ArithmeticCalculator.*(int, int))",
    returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        List<Object> args = Arrays.asList(joinPoint.getArgs());

        System.out.println("The method  ends witd " + result);
    }

    //在目标方法出现异常时会执行的代码
    //可以访问到异常对象;且可以指定在出现特定异常时再执行通知代码
    @AfterThrowing(value = "execution(public int ArithmeticCalculator.*(int, int))",
            throwing = "ex")
    public void afterReturning(JoinPoint joinPoint, Exception ex) {
        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " +  methodName + " occures exception with: " + ex);
    }

    /**
     * 环绕通知需要携带ProceedingJoinPoint类型的参数
     * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法
     * 且环绕通知必须有返回值,返回值为目标方法的返回值
     * @param proceedingJoinPoint
     */
    @Around("execution(public int ArithmeticCalculator.*(int, int))")
    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) {
        Object result = null;
        String methodName = proceedingJoinPoint.getSignature().getName();
        //执行目标方法
        try {
            //前置通知
            System.out.println("The method " +  methodName + " begins with " + Arrays.asList(proceedingJoinPoint.getArgs()));
            result = proceedingJoinPoint.proceed();
            //返回通知
            System.out.println("The method ends with " + result);
        } catch (Throwable throwable) {
            //异常通知
            System.out.println("The method " +  methodName + " occures exception with: " + throwable);
            throw new RuntimeException(throwable);
        }
        //后置通知
        System.out.println("The method " +  methodName + " ends");
        return result;
    }
}
package com.cn.spring.aop.impl;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * Created by jecyhw on 2015/6/21.
 */
@Order(1)
@Aspect
@Component
public class ValidationAspect {

    @Before("execution(public int ArithmeticCalculator.*(..))")
    public void validateArgs(JoinPoint joinPoint) {
        System.out.println("validate:" + Arrays.asList(joinPoint.getArgs()));
    }
}
package com.cn.spring.aop.impl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        //1.创建Spring的IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("17-1.xml");

        //2.从IOC容器中huo获取bean的实例
        ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);

        //3.使用bean
        int result = arithmeticCalculator.add(3, 6);

        System.out.println("result:" + result);
        //result = arithmeticCalculator.div(3, 0);
       // System.out.println("result:" + result);
    }
}
<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <context:component-scan base-package="com.cn.spring.aop.impl">
    </context:component-scan>

    <!--使AspjectJ注解起作用:自动为匹配的类生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
 
时间: 2024-09-26 20:09:25

20Spring切面的优先级的相关文章

Spring-AOP的五种通知和切面的优先级

SpringAOP的通知分为以下五种: 1前置通知(@before)在连接点执行之前执行的代码 2后置通知(@after)在连接点执行之后执行的代码,不管连接点执行后是否出现异常,后置通知都会执行,但是不能访问连接点返回值 3返回通知返回通知:就是可以获取连接点的返回值,  当连接点执行之后,若没有异常,则执行返回通知,返回通知在后置通知执行后才会执行 4异常通知在连接点执行的时候,若出现异常,则会执行异常通知,可以根据异常类型来定义执行对应的异常通知 5环绕通知相当于一个动态代理,也就是说其动

Spring(十九):Spring AOP(三):切面的优先级

背景: 1)指定切面优先级示例:有的时候需要对一个方法指定多个切面,而这多个切面有时又需要按照不同顺序执行,因此,切面执行优先级别指定功能就变得很实用. 2)重复使用切入点表达式:上一篇文章中,定义前置.后置.返回.异常通知的切入点表达式时,都使用了同一个:而且本章节新加入的验证切面ValidateAspect类,也使用同一个切入点表达式,怎么让他们重用呢? 指定切面优先级示例: 比如在算术计算器执行计算之前进行数据验证,验证完事之后才让执行日志输出. 新建spring aop项目参考:<Spr

Spring4深入理解AOP02----AOP简介,AspectJ基于注解(5种通知,切面优先级)

参考代码下载github:https://github.com/changwensir/java-ee/tree/master/spring4 一.AOP简介 ?AOP(Aspect-Oriented Programming, 面向切面编程):是一种新的方法论,是对传统OOP(Object-OrientedProgramming,面向对象编程)的补充. ?AOP 的主要编程对象是切面(aspect),而切面模块化横切关注点. ?在应用 AOP 编程时,仍然需要定义公共功能,但可以明确的定义这个功

Spring 切面优先级

之前我们提过的应用场景,一个原始对象可能会需要插入多个切面,如果我们按前几篇博客文章介绍的方法完成切面及其通知的注解声明,那么它的执行顺序是怎么样的呢? 本文将介绍AspectJ的切面如何划分优先级 指定切面的优先级 在同一个连接点上应用不止一个切面时, 除非明确指定, 否则它们的优先级是不确定的. 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. 实现 Ordered 接口, getOrder() 方法的返回值越小, 优先级越高. 若使用 @Order 注解, 序

Spring 切面优先级(5)

之前我们提过的应用场景,一个原始对象可能会需要插入多个切面,如果我们按前几篇博客文章介绍的方法完成切面及其通知的注解声明,那么它的执行顺序是怎么样的呢? 本文将介绍AspectJ的切面如何划分优先级 指定切面的优先级 在同一个连接点上应用不止一个切面时, 除非明确指定, 否则它们的优先级是不确定的. 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. 实现 Ordered 接口, getOrder() 方法的返回值越小, 优先级越高. 若使用 @Order 注解, 序

Spring框架——AOP(面向切面编程)详解

 1 AOP概述 ●AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Programming,面向对象编程)的补充. ●AOP编程操作的主要对象是切面(aspect),而切面模块化横切关注点. ●在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应用在哪里,以什么方式应用,并且不必修改受影响的类.这样一来横切关注点就被模块化到特殊的类里--这样的类我们通常称之为"切面".

使用Spring进行面向切面编程(AOP)

转载于http://www.blogjava.net/supercrsky/articles/174368.html 文章太长,写的很好,没看完,转过来慢慢理解,品味 简介 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足. 除了类(classes)以外,AOP提供了 切面.切面对关注点进行模块化,例如横切多个类型和对象的事务管理. (这些关注点术语通常称作 横切(crosscutting) 关注点.) Spring的一个关键的组件就是 AOP

AOP面向切面编程笔记

1.AOP概念:Aspect Oriented Programming 面向切面编程 2.作用:本质上来说是一种简化代码的方式 继承机制 封装方法 动态代理 -- 3.情景举例 ①数学计算器接口[MathCalculator] int add(int i,int j); int sub(int i,int j); int mul(int i, int j); int div(int i,int j); ②提供简单实现[EasyImpl] ③在简单实现的基础上让每一个计算方法都能够打印日志[Log

Spring(三)--AOP【面向切面编程】、通知类型及使用、切入点表达式

1.概念:Aspect Oriented Programming 面向切面编程 在方法的前后添加方法 2.作用:本质上来说是一种简化代码的方式 继承机制 封装方法 动态代理 -- 3.情景举例 ①数学计算器接口[MathCalculator] int add(int i,int j); int sub(int i,int j); int mul(int i, int j); int div(int i,int j); 因为后面的通知方法需要返回值,所以在这里类型声明为 int 类型 public