業精於勤疏於嬉,行成於思毀於隨。
創建環繞通知
環繞通知是最強大的通知類型,它能夠讓你所編寫的邏輯將被通知的目標方法完全包裝起來,實際它就像在一個通知方法中同時編寫前置通知和后置通知。
Spring使用@Around注解聲明環繞通知。
package chapter4.practice1; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** * POJO * 使用@Aspect標注該POJO也是切面 */ @Aspect public class Audience { /** * 使用@Pointcut設置切點表達式 */ @Pointcut("execution(** chapter4.practice1.Performance.perform(..))") public void performance() {} @Around("performance()") public void watchPerformance(ProceedingJoinPoint jp) { try { System.out.println("Siliencing cell phones..."); System.out.println("Taking seats...");
//目標方法執行前 jp.proceed();
//目標方法執行后 System.out.println("CLAP CLAP..."); } catch (Throwable e) { System.out.println("Demanding a refund..."); } } }
ProceedingJoinPoint的proceed()方法
/******************************************************************************* * Copyright (c) 2005 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html * * Contributors: * initial implementation Alexandre Vasseur *******************************************************************************/ package org.aspectj.lang; import org.aspectj.runtime.internal.AroundClosure; /** * ProceedingJoinPoint exposes the proceed(..) method in order to support around advice in @AJ aspects * * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public interface ProceedingJoinPoint extends JoinPoint { /** * The joinpoint needs to know about its closure so that proceed can delegate to closure.run() * <p/> * This internal method should not be called directly, and won't be visible to the end-user when * packed in a jar (synthetic method) * * @param arc */ void set$AroundClosure(AroundClosure arc); /** * Proceed with the next advice or target method invocation * * @return * @throws Throwable */ public Object proceed() throws Throwable; /** * Proceed with the next advice or target method invocation * <p/> * <p>Unlike code style, proceed(..) in annotation style places different requirements on the * parameters passed to it. The proceed(..) call takes, in this order: * <ul> * <li> If 'this()' was used in the pointcut for binding, it must be passed first in proceed(..). * <li> If 'target()' was used in the pointcut for binding, it must be passed next in proceed(..) - * it will be the first argument to proceed(..) if this() was not used for binding. * <li> Finally come all the arguments expected at the join point, in the order they are supplied * at the join point. Effectively the advice signature is ignored - it doesn't matter * if a subset of arguments were bound or the ordering was changed in the advice signature, * the proceed(..) calls takes all of them in the right order for the join point. * </ul> * <p>Since proceed(..) in this case takes an Object array, AspectJ cannot do as much * compile time checking as it can for code style. If the rules above aren't obeyed * then it will unfortunately manifest as a runtime error. * </p> * * @param args * @return * @throws Throwable */ public Object proceed(Object[] args) throws Throwable; }
proceed()方法會阻塞對被通知方法的調用。
