zoukankan      html  css  js  c++  java
  • spring通知执行的顺序

    点击下载本示例相关代码

    关于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("
    ========================
    ");
            aservice.m1();
            System.out.println("
    ========================
    ");
            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

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







  • 相关阅读:
    Oracle11g 审计介绍
    用Go向MySQL导入.csv文件
    【Lucene】实现全文索引
    redis-3.0.1 sentinel 主从高可用 详细配置
    MySQL性能优化之max_connections配置
    数据结构算法
    inux 软件编译、安装、删除
    2015年,才开始流行的几个教育观念
    常见的几种语言函数调用约定
    关于代码调试de那些事
  • 原文地址:https://www.cnblogs.com/itsoku123/p/10744345.html
Copyright © 2011-2022 走看看