Spring AOP 四大通知

Spring 3.X 以前

1.前置通知,实现  MethodBeforeAdvice 接口,重写

public  void  before(Method  method, Object[]  args, Object  target) throws Throwable方法

    

    import java.lang.reflect.Method;

    import org.springframework.aop.MethodBeforeAdvice;

    public class TestMethodBeforeAdvice implements MethodBeforeAdvice {

        /** arg0  方法

        * arg1 参数

        * arg2 操作对象

        * */

        @Override

        public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {

          System.out.println("前置通知:----》方法:"+arg0.getName()+"传入参数"+arg1+"操作象"+arg2);

        }

     }

2.后置通知,实现 AfterReturningAdvice  接口,重写

      public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable 方法

      import java.lang.reflect.Method;

      import org.springframework.aop.AfterReturningAdvice;

      public class TestAfterReturningAdvice implements AfterReturningAdvice{

            /**

            * arg0:return 的返回值

            * arg1:执行的方法对象

            * arg2:方法执行中传递过来的参数

            * arg3:执行方法的对象

            */

            @Override

            public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {

              System.out.println("后置通知:----》方法:"+arg1.getName()+"返回值:"+arg0+"执行方对象:"+arg3);

            }  

      }

3.环绕通知, 实现 MethodInterceptor  接口,重写

      public  Object  invoke(MethodInvocation  invocation) throws Throwable 方法

      import java.lang.reflect.Method;

      import org.aopalliance.intercept.MethodInterceptor;

      import org.aopalliance.intercept.MethodInvocation;

      public class TestMethodinterceptor implements MethodInterceptor {

          @Override

          public Object invoke(MethodInvocation invocation) throws Throwable {

              Method method = invocation.getMethod() ; //方法

              Object[] objs = invocation.getArguments() ; //参数

              Object obj = invocation.getThis() ; //操作对象

              System.out.println("环绕通知:-----》 开始: 方法:"+method.getName()+"传入的参数:"+objs+" 操作对象:"+obj);

              Object result = invocation.proceed() ;   //放行

              System.out.println("环绕通知:-----》 结束:  返回值:"+result);

              return result ;

          }

      }

4.异常通知,实现 ThrowsAdvice 接口,重写

public void afterThrowing(Method  m, Object  args, Object  target,Throwable  e) 方法

    import java.lang.reflect.Method;

    import org.springframework.aop.ThrowsAdvice;

    public class TestThrowsAdvice implements ThrowsAdvice {

        public void afterThrowing(Method m, Object args, Object target, Throwable e) {

          System.out.println("异常通知:方法"+m.getName()+"发生异常,"+e.getMessage());

           System.exit(0);

        }

     }

注意:查看ThrowsAdvice源码会发现这个接口里面没有定义方法,但是这个方法必须这么写,

Spring 3.X 以后版本

 

    import org.aspectj.lang.JoinPoint;

    import org.aspectj.lang.ProceedingJoinPoint;

    public class TestAdvice {

       public void before(JoinPoint joinPoint){ //前置通知

          System.out.println("操作者"+joinPoint.getTarget()+"参数             "+joinPoint.getArgs()[0]);

          System.out.println("*********************前置通知*********************");

       }

       //后置通知:当方法执行完会触发,出错则不执行

       public void afterReturning(JoinPoint joinPoint,Object obj){

            System.out.println("后置通知");

            System.out.println("返回结果:"+obj);

        }

        //最终通知

        public void after(JoinPoint joinPoint){

            System.out.println("最终通知");

            System.out.println("调用的方法"+joinPoint.getSignature());

        }

        //异常通知

        public void throwAdvice(Exception exception){

            System.out.println("--------异常通知--------");

            System.out.println("异常消息"+exception.getMessage());

        }

        //环绕通知

        public Object around(ProceedingJoinPoint proceedingJoinPoint){

            System.out.println("环绕通知开始");

            try {

              Object  obj = proceedingJoinPoint.proceed() ;

              System.out.println("环绕通知结束");

              return obj ;

            } catch (Throwable e) {

              e.printStackTrace();

            }

            return null ;

      }

  }

配置信息

<!--Spring3.X以前-->

<!--后置通知-->

  <bean id="afterAdvice" class="com.spring.advice.TestAfterReturningAdvice"/>

<!--前置通知-->

  <bean id="beforeAdvice" class="com.spring.advice.TestMethodBeforeAdvice"/>

<!--环绕通知-->

  <bean id="interceptorAdvice" class="com.spring.advice.TestMethodinterceptor"/>

<!--异常通知-->

  <bean id="throwsAdvice" class="com.spring.advice.TestThrowsAdvice"/>

<!--Spring3.X以后整合-->

  <bean id="advice" class="com.spring.advice.TestAdvice"/>

<!-- AOP设置 -->

<aop:config>

    <aop:pointcut expression="execution(* com.spring.service.*.*(..))" id="mycut"/>

    <aop:advisor advice-ref="afterAdvice" pointcut-ref="mycut"/>

    <aop:advisor advice-ref="beforeAdvice" pointcut-ref="mycut"/>

    <aop:advisor advice-ref="interceptorAdvice" pointcut-ref="mycut"/>

    <aop:advisor advice-ref="throwsAdvice" pointcut-ref="mycut"/>

    <!-- 新版本 -->

    <aop:aspect ref="advice">

        <aop:before method="before" pointcut-ref="mycut"/>

        <aop:after-returning method="afterReturning" returning="obj" pointcut-ref="mycut"/>

        <aop:after method="after" pointcut-ref="mycut"/>

        <aop:after-throwing method="throwAdvice" throwing="exception" pointcut-ref="mycut"/>

        <aop:around method="around" pointcut-ref="mycut"/>

     </aop:aspect>

</aop:config>

两种方法:

  Spring3.X版本以前写法思路更清晰,新版本,虽然把4个通知整合在了一起,但是,如果业务复杂的话,通知较多建议分开写,

两种方法区别不是很大,具体还得开需求

expression的value值

任意公共方法的执行:

  execution(public * *(..))

任何一个以“set”开始的方法的执行:

  execution(* set*(..))

AccountService 接口的任意方法的执行:

  execution(* com.xyz.service.AccountService.*(..))

定义在service包里的任意方法的执行:

  execution(* com.xyz.service.*.*(..))

定义在service包或者子包里的任意方法的执行:

  execution(* com.xyz.service..*.*(..))

若要转载,请标明此处

Spring AOP 四大通知的更多相关文章

  1. Spring笔记07(Spring AOP的通知advice和顾问advisor)

    1.Spring AOP的通知advice 01.接口代码: package cn.pb.dao; public interface UserDao { //主业务 String add(); //主 ...

  2. spring aop 环绕通知around和其他通知的区别

    前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知   是不能决定的,他们只 ...

  3. spring aop环绕通知

    [Spring实战]—— 9 AOP环绕通知   假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Sprin ...

  4. Spring AOP前置通知和后置通知

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

  5. Spring AOP高级——源码实现(2)Spring AOP中通知器(Advisor)与切面(Aspect)

    本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/Spring%20AOP%E9%A ...

  6. [转载] spring aop 环绕通知around和其他通知的区别

    前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知   是不能决定的,他们只 ...

  7. Spring AOP前置通知实例说明AOP相关概念

    今天又看了下韩顺平的SpringAOP的讲解,讲解的很透彻.仿照视频自己使用下前置通知. 一.引出问题 有个接口TestServiceInter,有两个实现方法TestService和Test2Ser ...

  8. Spring AOP前置通知实例讲解与AOP详细解析

    一.引出问题 有个接口TestServiceInter,有两个实现方法TestService和Test2Service.他们都有sayHello():我们的需求是在调用这两个方法之前,要先完成写日志的 ...

  9. 【Spring AOP】通知(五)

    一.通知介绍 1. 前置通知(Before) 在目标方法执行之前执行的通知. 前置通知方法,可以没有参数,也可以额外接收一个JoinPoint,Spring会自动将该对象传入,代表当前的连接点,通过该 ...

随机推荐

  1. Java实时读取日志文件

    古怪的需求 在实习的公司碰到一个古怪的需求:在一台服务器上写日志文件,每当日志文件写到一定大小时,比如是1G,会将这个日志文件改名成另一个名字,并新建一个与原文件名相同的日志文件,再往这个新建的日志文 ...

  2. Javascript动画效果(四)

    Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...

  3. linux如何编译安装新内核支持NTFS文件系统?(以redhat7.2x64为例)

    内核,是一个操作系统的核心.它负责管理系统的进程.内存.设备驱动程序.文件和网络系统,决定着系统的性能和稳定性.Linux作为一个自由软件,在广大爱好者的支持下,内核版本不断更新.新的内核修订了旧内核 ...

  4. JavaScript DOM学习总结(一)

    DOM 什么是DOM?简单地说DOM是一套对文档内容进行抽象和概念化的方法.   W3C给出的DOM定义是这样的:"一个与系统平台和编程语言无关的接口,程序和脚本以通过这个接口动态的访问和修 ...

  5. linux useradd 命令基本用法

    在 Linux 中 useradd 是个很基本的命令,但是使用起来却很不直观.以至于在 Ubuntu 中居然添加了一个 adduser 命令来简化添加用户的操作.本文主要描述笔者在学习使用 usera ...

  6. .net请求Webservice简单实现天气预报功能

    很久没有接触Webservice的知识,今天稍微复习了一下关于webservice,简单做了一个天气预报的功能,虽然界面丑的厉害,但功能算是实现了,以下是效果展示. 这东西没什么难点,只是天气预报的功 ...

  7. OCP开放封闭原则

    一.定义 软件实体(类.模块.函数等)应该是可以扩展的,但是不可修改. 如果正确的应用了OCP原则,那么 以后在进行同样的改动时,就只需要添加新的代码,不必修改已经正常运行的代码. 二.OCP概述 1 ...

  8. 炉石传说 C# 开发笔记 (续)

    炉石传说山寨的工作一直在进行着,在开发过程中深深体会到,对于业务的理解和整个程序的架构的整理远比开发难得多. 在开发过程中,如果你的模型不合理,不准确,很有可能造成代码的混乱,冗余,难以维护和扩展性比 ...

  9. Delphi 10.1 Berlin 官方未列之修正

    Delphi 10.1 Berlin 官方修正列表: Bug fix list for RAD Studio 10.1 Berlin Delphi 10.1 Berlin 官方未列之修正: 修正 iO ...

  10. bitbucket+sourcetree+p4merge for windows 版本控制

    这里选择bitbucket作为仓库的原因是,它能够在设置私有仓库的前提下组建5人团队 一:https://bitbucket.org/ 注册bitbucket 二:http://www.sourcet ...