1. 程式人生 > >spring 12-Spring框架AOP深入配置

spring 12-Spring框架AOP深入配置

AOP深入配置可以實現以下功能:

  • 前置通知的引數傳遞
  • 返回通知
  • 針對異常進行處理

1、定義業務層介面和子類

package cn.liang.service;
public interface IMessageService {
  public boolean remove(String mid) ;
}
package cn.liang.service.impl;
import org.apache.log4j.Logger;
import cn.liang.service.IMessageService;
public class MessageServiceImpl implements IMessageService {
  @Override
  public boolean remove(String mid) {
      Logger.getLogger(IMessageService.class).info("【業務層】執行刪除呼叫,刪除的資料ID = " + mid);
      return false;
  }
}

2、定義一個描述AOP程式處理的結構類

package cn.liang.service.proxy;
import org.apache.log4j.Logger;
public class ServiceProxy {
  public void beforeInvoke(Object arg) {
      Logger.getLogger(ServiceProxy.class).info("【ServiceProxy - BEFORE】在業務方法執行之前進行呼叫,引數內容:" + arg);
  } 
  public void throwInvoke(Exception e) {
      Logger.getLogger(ServiceProxy.class).error("【ServiceProxy - EXCEPTION】丟擲異常:" + e);
  }
  public void afterInvoke() {
      Logger.getLogger(ServiceProxy.class).info("【ServiceProxy - AFTER】在業務方法執行之後進行呼叫。");
  }
  public void returnInvoke(Object val) {
      Logger.getLogger(ServiceProxy.class).info("【ServiceProxy - RETURNING】返回值 = " + val);
  }   
}

3、配置applicationContext.xml檔案

<bean id="messageServiceImpl" class="cn.liang.service.impl.MessageServiceImpl"/>
<bean id="serviceProxy" class="cn.liang.service.proxy.ServiceProxy"/>
<aop:config>
  <aop:pointcut expression="execution(* cn.liang.service..*.*(..)) and args(id)"
      id="defaultPointCut" />
  <aop:aspect ref="serviceProxy">
      <aop:before method="beforeInvoke" pointcut-ref="defaultPointCut"
          arg-names="id" />
      <aop:after method="afterInvoke" pointcut="execution(* cn.liang.service..*.*(..))" />
      <aop:after-returning method="returnInvoke"
          pointcut="execution(* cn.liang.service..*.*(..))" returning="v"
          arg-names="v" />
      <aop:after-throwing method="throwInvoke"
          pointcut="execution(* cn.liang.service..*.*(..))" throwing="e"
          arg-names="e" />
  </aop:aspect>
</aop:config>

4、編寫測試程式

package cn.liang.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.liang.service.IMessageService;
public class TestAOP {
  public static void main(String[] args) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
      IMessageService msgService = ctx.getBean("messageServiceImpl", IMessageService.class);
      System.out.println(msgService.remove("101"));
  }
}

5、輸出結果

2018-12-05 16:54:01,793 INFO [cn.liang.service.proxy.ServiceProxy] - 【ServiceProxy - BEFORE】在業務方法執行之前進行呼叫,引數內容:101
2018-12-05 16:54:01,794 INFO [cn.liang.service.IMessageService] - 【業務層】執行刪除呼叫,刪除的資料ID = 101
2018-12-05 16:54:01,794 INFO [cn.liang.service.proxy.ServiceProxy] - 【ServiceProxy - AFTER】在業務方法執行之後進行呼叫。
2018-12-05 16:54:01,794 INFO [cn.liang.service.proxy.ServiceProxy] - 【ServiceProxy - RETURNING】返回值 = false
false

AOP深入配置之環繞通知

1、定義一個描述AOP程式處理的環繞通知結構類

package cn.liang.service.proxy;
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
public class ServiceProxy {
  // 如果要進行後續呼叫需要知道傳遞的引數,需要知道具體要呼叫的業務方法
      public Object arroundInvoke(ProceedingJoinPoint point) throws Throwable {
          Logger.getLogger(ServiceProxy.class).info("【*** BEFORE ***】執行引數:" + Arrays.toString(point.getArgs())); 
          // Object obj = point.proceed(point.getArgs()) ;正常操作要將使用者的引數繼續向後傳遞
          Object obj = point.proceed(new Object[] {"1234"} ) ;    // 自己來處理引數內容
          Logger.getLogger(ServiceProxy.class).info("【*** AFTER ***】返回結果:" + obj);
          return true ;
      }   
}

2、配置applicationContext.xml檔案

<bean id="messageServiceImpl" class="cn.liang.service.impl.MessageServiceImpl"/>
<bean id="serviceProxy" class="cn.liang.service.proxy.ServiceProxy"/>
 <aop:config>
  <aop:pointcut expression="execution(* cn.liang.service..*.*(..))" id="defaultPointCut" />
  <aop:aspect ref="serviceProxy">
      <aop:around method="arroundInvoke" pointcut-ref="defaultPointCut"/>
  </aop:aspect>
 </aop:config>

3、使用TestAOP測試結果

2018-12-05 17:01:18,190 INFO [cn.liang.service.proxy.ServiceProxy] - 【*** BEFORE ***】執行引數:[101]
2018-12-05 17:01:18,190 INFO [cn.liang.service.IMessageService] - 【業務層】執行刪除呼叫,刪除的資料ID = 1234
2018-12-05 17:01:18,190 INFO [cn.liang.service.proxy.ServiceProxy] - 【*** AFTER ***】返回結果:false
true