Spring AOP 環繞通知

Spring AOP的環繞通知和前置、後置通知有着很大的區別,主要有兩個重要的區別:

1)目標方法的調用由環繞通知決定,即你可以決定是否調用目標方法,而前置和後置通知是不能決定的,它們只是在方法的調用前後執行通知而已,即目標方法肯定是要執行的。joinPoint.proceed()就是執行目標方法的代碼。

2)環繞通知可以控制返回對象,即可以返回一個與目標對象完全不同的返回值。雖然這很危險,但是卻可以做到。


下面的例子使用環繞通知,完成日誌寫入。

1)Spring配置文件加入AOP定義

    <!--配置第三方平臺請求日誌切面-->  
    <bean id="logHandler" class="com.test.LogHandler" />  
    <aop:config>  
        <aop:aspect id="logAspect" ref="logHandler">  
            <aop:pointcut id="logPointCut" expression="execution(public * com.test.itf.*Ctr.*Hdl(..))"/>                
            <aop:around method="doAround"  pointcut-ref="logPointCut"/>  
        </aop:aspect>  
    </aop:config>  


2)通知處理類的定義

public class LogHandler {
	
	Logger logger = LoggerFactory.getLogger(LogHandler.class);
	
	@Resource(name="logService")
	private LogService logService; 
	
	public Object doAround(ProceedingJoinPoint joinPoint){
		try{
			Object ret = joinPoint.proceed(); //執行目標方法
			Object[] args =joinPoint.getArgs(); //獲取目標方法參數
			String arg0 = joinPoint.getSignature().getDeclaringTypeName();
			HttpServletRequest request =null ;
			for(int i=0;i<args.length;i++){
				if(args[i] instanceof HttpServletRequest ){
					request = (HttpServletRequest) args[i];  //獲取request參數對象
					break;
				}
			}
			JdResponse resp = (JdResponse) ret;  //目標方法執行返回的對象
			ConsumerLog log = new ConsumerLog();
			log.setId(UuidUtil.get32UUID());
			log.setCreateDate(new Date());
			log.setAppId(request.getParameter("appId"));
			log.setNonceStr(request.getParameter("nonceStr"));
			log.setOutput(JSONObject.toJSONString(resp));
			log.setInput(getHttpParameters(request));
			logService.insertLog(log);  //寫入日誌表
			return resp;
			
		}catch(Throwable e){
			logger.error("error in logService doArround:",e);
			return new JdResponse(JdResponse.CODE.serverError,"系統錯誤",null);
		}
	}
ProceedingJoinPoint對象表示連接點對象,該類是JoinPoint的子接口。該對象由spring自動傳值,實現客戶端給具體實現類的參數傳遞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章