• Spring AOP 四大通知


    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..*.*(..))

    若要转载,请标明此处

  • 相关阅读:
    函数—函数进阶(二)
    函数—函数进阶(一)
    函数(三)
    函数(二)
    函数(一)
    人丑就要多读书、三元运算、文件处理
    第二章练习题
    Python bytes类型介绍、Python3与2字符串的区别、Python3与2编码总结
    进制运算、字符编码、Python3的执行流程
    去除inline-block元素间间距,比较靠谱的两种办法
  • 原文地址:https://www.cnblogs.com/ChangFen/p/5922821.html
Copyright © 2020-2023  润新知