点击下载本示例相关代码

关于spring aop的具体使用,暂时不在这里讲解,后面会特定来讲解,本次主要探讨spring中通知执行的顺序。

spring中通知分为以下几种:

  1. before:前置通知,在方法执行之前执行
  2. around:环绕通知,在方法执行前后执行
  3. afterreturning:在方法执行成功后执行
  4. afterthrowning:异常通知,在方法发生异常后执行
  5. after:后置通知,在方法执行之后执行(不管方法执行成功还是失败)

下面我们将每种通知创建两个,代码如下:
1、before通知2个
package com.cn.aop.demo4;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class Before1 {
@Before(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(Before1.class+" Before通知 order = "+order.value());
}
}
package com.cn.aop.demo4;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class Before2 {
@Before(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(Before2.class+" Before通知 order = "+order.value());
}
}

2、around通知2个

package com.cn.aop.demo4;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class Around1 {
@Around(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public Object exec(ProceedingJoinPoint invocation) throws Throwable {
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(Around1.class+" Around通知 order = "+order.value()+" start");
Object result = invocation.proceed();
System.out.println(Around1.class+" Around通知 order = "+order.value()+" end");
return result;
}
}
package com.cn.aop.demo4;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class Around2 {
@Around(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public Object exec(ProceedingJoinPoint invocation) throws Throwable {
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(Around2.class+" Around通知 order = "+order.value()+" start");
Object result = invocation.proceed();
System.out.println(Around2.class+" Around通知 order = "+order.value()+" end");
return result;
}
}

3、afterreturning通知2个

package com.cn.aop.demo4;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class AfterReturning1 {
@AfterReturning(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(AfterReturning1.class+" AfterReturning通知 order = "+order.value());
}
}
package com.cn.aop.demo4;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class AfterReturning2 {
@AfterReturning(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(AfterReturning2.class+" AfterReturning通知 order = "+order.value());
}
}

4、afterthrowning通知2个

package com.cn.aop.demo4;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class AfterThrowing1 {
@AfterThrowing(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(AfterThrowing1.class+" AfterThrowing通知 order = "+order.value());
}
}
package com.cn.aop.demo4;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class AfterThrowing2 {
@AfterThrowing(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(AfterThrowing2.class+" AfterThrowing通知 order = "+order.value());
}
}

5、after通知两个

package com.cn.aop.demo4;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order
public class After1 {
@After(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(After1.class+" After通知 order = "+order.value());
}
}
package com.cn.aop.demo4;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 我的技术网站 2016/11/17 0017.
*/
@Component
@Aspect
@Order(100000)
public class After2 {
@After(value = "execution(* com.cn.aop.demo4.*Impl.*(..))")
public void exec(){
Order order = this.getClass().getAnnotation(Order.class);
System.out.println(After2.class+" After通知 order = "+order.value());
}
}

6、其他文件

  • 声明1个接口和一个实现类,在本实现类上面添加上面10个通知
package com.cn.aop.demo4;

/**
* 我的技术网站 2016/11/15 0015.
*/
public interface IAService {
String m1();
void m2();
}
package com.cn.aop.demo4;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* 我的技术网站 2016/11/15 0015.
*/
@Component("aservice")
public class AServiceImpl implements IAService { public String m1()
{
System.out.println(AServiceImpl.class+".m1()");
return AServiceImpl.class+".m1()";
} @Override
public void m2() {
int i=0;
System.out.println(10/i);
}
}
  • spring配置文件spring-demo4.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd" default-autowire="byName">
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.cn.aop.demo4"/>
</beans>

  • 测试类
package com.cn.aop.demo4;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* 我的技术网站 2016/11/17 0017.
*/
public class Client {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/aop/spring-demo4.xml");
IAService aservice = context.getBean("aservice", IAService.class);
System.out.println("\n========================\n");
aservice.m1();
System.out.println("\n========================\n");
try {
aservice.m2();
} catch (Exception e){
//暂时不输出错误信息
}
}
}

1、上面所有拦截器的order都为100000,执行结果如下

========================

class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.Before1 Before通知 order = 100000
class com.cn.aop.demo4.Before2 Before通知 order = 100000
class com.cn.aop.demo4.AServiceImpl.m1()
class com.cn.aop.demo4.Around2 Around通知 order = 100000 end
class com.cn.aop.demo4.Around1 Around通知 order = 100000 end
class com.cn.aop.demo4.AfterReturning1 AfterReturning通知 order = 100000
class com.cn.aop.demo4.AfterReturning2 AfterReturning通知 order = 100000
class com.cn.aop.demo4.After2 After通知 order = 100000
class com.cn.aop.demo4.After1 After通知 order = 100000 ======================== class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.Before1 Before通知 order = 100000
class com.cn.aop.demo4.Before2 Before通知 order = 100000
class com.cn.aop.demo4.AfterThrowing2 AfterThrowing通知 order = 100000
class com.cn.aop.demo4.AfterThrowing1 AfterThrowing通知 order = 100000
class com.cn.aop.demo4.After2 After通知 order = 100000
class com.cn.aop.demo4.After1 After通知 order = 100000

2、修改配置

Before1 @Order(1)
Before2 @Order(2)

client执行结果

========================

class com.cn.aop.demo4.Before1 Before通知 order = 1
class com.cn.aop.demo4.Before2 Before通知 order = 2
class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.AServiceImpl.m1()
class com.cn.aop.demo4.Around2 Around通知 order = 100000 end
class com.cn.aop.demo4.Around1 Around通知 order = 100000 end
class com.cn.aop.demo4.AfterReturning1 AfterReturning通知 order = 100000
class com.cn.aop.demo4.AfterReturning2 AfterReturning通知 order = 100000
class com.cn.aop.demo4.After2 After通知 order = 100000
class com.cn.aop.demo4.After1 After通知 order = 100000 ======================== class com.cn.aop.demo4.Before1 Before通知 order = 1
class com.cn.aop.demo4.Before2 Before通知 order = 2
class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.AfterThrowing2 AfterThrowing通知 order = 100000
class com.cn.aop.demo4.AfterThrowing1 AfterThrowing通知 order = 100000
class com.cn.aop.demo4.After2 After通知 order = 100000
class com.cn.aop.demo4.After1 After通知 order = 100000

3、修改配置
Before1 @Order(1)
Before2 @Order(2)
AfterReturning1 @Order(1)
AfterReturning2 @Order(1000001)
AfterThrowing1 @Order(1)
AfterThrowing2 @Order(1000001)
After1 @Order(1)
After2 @Order(1000001)

执行结果:

========================

class com.cn.aop.demo4.Before1 Before通知 order = 1
class com.cn.aop.demo4.Before2 Before通知 order = 2
class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.AServiceImpl.m1()
class com.cn.aop.demo4.AfterReturning2 AfterReturning通知 order = 1000001
class com.cn.aop.demo4.After2 After通知 order = 1000001
class com.cn.aop.demo4.Around2 Around通知 order = 100000 end
class com.cn.aop.demo4.Around1 Around通知 order = 100000 end
class com.cn.aop.demo4.AfterReturning1 AfterReturning通知 order = 1
class com.cn.aop.demo4.After1 After通知 order = 1 ======================== class com.cn.aop.demo4.Before1 Before通知 order = 1
class com.cn.aop.demo4.Before2 Before通知 order = 2
class com.cn.aop.demo4.Around1 Around通知 order = 100000 start
class com.cn.aop.demo4.Around2 Around通知 order = 100000 start
class com.cn.aop.demo4.AfterThrowing2 AfterThrowing通知 order = 1000001
class com.cn.aop.demo4.After2 After通知 order = 1000001
class com.cn.aop.demo4.AfterThrowing1 AfterThrowing通知 order = 1
class com.cn.aop.demo4.After1 After通知 order = 1

结论:

1、无异常情况
  • 所有通知order一样,执行顺序:around start -> before ->around
    start -> afterreturning -> after
  • before.order < around.order,执行顺序: before -> around start
  • afterreturning.order > around.order,执行顺序:afterreturning -> around
    end
  • after.order > around.order,执行顺序:after -> around
    end
  • after.order >afterreturning.order,执行顺序:
    after -> afterreturning
2、异常情况
  • 所有通知order一样,执行顺序:around start -> before ->  afterthrowing -> after
  • before.order < around.order,执行顺序: before -> around start
  • after.order > afterthrowing .order,执行顺序:after -> afterthrowing

如果喜欢,点个赞,关注公众号,我们将最好的内容分享与你!谢谢!




spring通知执行的顺序的更多相关文章

  1. Spring切面通知执行的顺序(Advice Order)

    问题描述 如果在Spring的程序中同时定义了环绕通知(Around)和前置通知(Before)..那么,有以下问题: 1.怎么让两个切面通知都起作用 2.或者让两者切面按自己指定的顺序进行执行? 3 ...

  2. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  3. spring多个AOP执行先后顺序(面试问题:怎么控制多个aop的执行循序)

    转载:spring多个AOP执行先后顺序(面试问题:怎么控制多个aop的执行循序) 众所周知,spring声明式事务是基于AOP实现的,那么,如果我们在同一个方法自定义多个AOP,我们如何指定他们的执 ...

  4. 【原】不定义Order属性,通过切面类的定义顺序来决定通知执行的先后顺序

    [结论] 在多个切面类的“切入点相同”并且每个切面都“没有定义order属性”的情况下,则切面类(中的通知)的执行顺序与该切面类在<aop:config>元素中“声明的顺序”相关,即先声明 ...

  5. 【原】Order属性决定了不同切面类中通知执行的先后顺序

    [障碍再现] MyBatis配置多数据源时,数据源切换失败. [原因分析]    自定义切面和Spring自带事务切面“即<aop:advisor>”执行的先后顺序导致数据源不能切换成功. ...

  6. Spring通知类型及使用ProxyFactoryBean创建AOP代理

    Spring 通知类型 通过前面的学习可以知道,通知(Advice)其实就是对目标切入点进行增强的内容,Spring AOP 为通知(Advice)提供了 org.aopalliance.aop.Ad ...

  7. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring通知类型及使用ProxyFactoryBean创建AOP代理

    通知(Advice)其实就是对目标切入点进行增强的内容,Spring AOP 为通知(Advice)提供了 org.aopalliance.aop.Advice 接口. Spring 通知按照在目标类 ...

  8. 使用@AutoConfigureBefore、After、Order调整Spring Boot自动配置顺序

    前言 Spring Boot是Spring家族具有划时代意义的一款产品,它发展自Spring Framework却又高于它,这种高于主要表现在其最重要的三大特性,而相较于这三大特性中更为重要的便是Sp ...

  9. Java中的继承与静态static等的执行先后顺序

    package extend; public class X { Y y=new Y(); static{  System.out.println("tttt"); } X(){  ...

随机推荐

  1. Shell 脚本中调用另一个 Shell 脚本的三种方式

    主要以下有几种方式: Command Explanation fork 新开一个子 Shell 执行,子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 ...

  2. 最新.net和Java调用SAP RFC中间件下载

    还记得2012年初我发布的全网络第一个关于.net 连接SAP RFC的NCO3原创博文,用的就是SAP出的最新的.Net Connector 3.0的版本,在那个时候都是普遍用其他蹩脚的方式或Web ...

  3. WebP 在减少图片体积和流量上的效果如何?MIP技术实践分享

    作者 | Jackson 编辑 | 尾尾 不论是 PC 还是移动端,图片一直占据着页面流量的大头,在图片的大小和质量之间如何权衡,成为了长期困扰开发者们的问题.而 WebP 技术的出现,为解决该问题提 ...

  4. 如何扩展分布式日志组件(Exceptionless)的Webhook事件通知类型?

    写在前面 从上一篇博客高并发.低延迟之C#玩转CPU高速缓存(附示例)到现在又有几个月没写博客了,啥也不说,变得越来越懒了,懒惰产生了拖延后遗症. 最近一周升级了微服务项目使用的分布式日志组件Exce ...

  5. TIMO后台管理系统-基于SpringBoot开发

    项目介绍 TIMO后台管理系统,基于SpringBoot2.0 + Spring Data Jpa + Thymeleaf + Shiro 开发的后台管理系统,采用分模块的方式便于开发和维护,支持前后 ...

  6. python接口自动化(二十三)--unittest断言——上(详解)

    简介 在测试用例中,执行完测试用例后,最后一步是判断测试结果是 pass 还是 fail,自动化测试脚本里面一般把这种生成测试结果的方法称为断言(assert).用 unittest 组件测试用例的时 ...

  7. Python猫荐书系列之五:Python高性能编程

    稍微关心编程语言的使用趋势的人都知道,最近几年,国内最火的两种语言非 Python 与 Go 莫属,于是,隔三差五就会有人问:这两种语言谁更厉害/好找工作/高工资…… 对于编程语言的争论,就是猿界的生 ...

  8. 小程序顶部navbar(非Slider)

    wxml(该导航栏的实现原理是当你要显示哪个view在最前端的时候隐藏其他的view): <!-- 顶部navbar导航栏 --> <view class="navbar& ...

  9. Android新手引导库推荐

    本文同步至http://javaexception.com/archives/31 介绍一波新手引导层的库.都是star数挺高的一些库. 1.NewbieGuide(国内开发者开发) Android ...

  10. Flutter的初体验--初次配置的问题

    首先参照官方文档进行搭建Mac下的环境 ,然后就会遇到以下问题:   1.在下载了Flutter 之后,执行Flutter doctor之后,报错: Could not resolve URL &qu ...