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

 

 

若要轉載,請標明此處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM