Notes

Notes: Spring AOP: 2: Advice

Ref: Spring documentation
Advice is associated with a pointcut expression, and runs before, after, or around method executions matched by the pointcut. The pointcut expression may be either a simple reference to a named pointcut, or a pointcut expression declared in place.

Before Advice
○ Before advice is declared in an aspect using the @Before annotation:

		import org.aspectj.lang.annotation.Aspect;
		import org.aspectj.lang.annotation.Before;
		
		@Aspect
		public class BeforeExample {
			@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
			public void doAccessCheck() {
				// ...
			}
			
			@Before("execution(* com.xyz.myapp.dao.*.*(..))")
			public void doAccessCheckWithInplacePointcut() {
			// ...
			}
		}

After-returning Advice

	○ @AfterReturning( pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
					returning="retVal")
	public void doAccessCheck(Object retVal) {
			// ...
	}

○ The name used in the returning attribute must correspond to the name of a parameter in the advice method.
○ When a method execution returns, the return value will be passed to the advice method as the corresponding argument value.
○ A returning clause also restricts matching to only those method executions that return a value of the specified type (Object in this case, which will match any return value).
○ Please note that it is not possible to return a totally different reference when using after-returning advice.

After throwing advice

	○  @AfterThrowing( pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
					throwing="ex")
	public void doRecoveryActions(DataAccessException ex) {
		// ...
	}

○ The name used in the throwing attribute must correspond to the name of a parameter in the advice method.
○ When a method execution exits by throwing an exception, the exception will be passed to the advice method as the corresponding argument value.
○ A throwing clause also restricts matching to only those method executions that throw an exception of the specified type (DataAccessException in this case).

After (finally) advice

 @After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doReleaseLock() {
		// ...
	}

Around advice

 @Around("com.xyz.myapp.SystemArchitecture.businessService()")
	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
		// start stopwatch
		Object retVal = pjp.proceed();
		// stop stopwatch
		return retVal;
	}

○ Around advice is declared using the @Around annotation.
○ The first parameter of the advice method must be of type ProceedingJoinPoint.
○ Within the body of the advice, calling proceed() on the ProceedingJoinPoint causes the underlying method to execute.
○ The proceed method may also be called passing in an Object[] – the values in the array will be used as the arguments to the method execution when it proceeds.
○ The value returned by the around advice will be the return value seen by the caller of the method. A simple caching aspect for example could return a value from a cache if it has one, and invoke proceed() if it does not.
○ Note that proceed may be invoked once, many times, or not at all within the body of the around advice, all of these are quite legal.

****************
Advice parameters

Access to the current JoinPoint
○ Any advice method may declare as its first parameter, a parameter of type org.aspectj.lang.JoinPoint
○ For around advice ProceedingJoinPoint is mandatory as the first argument.
○ JoinPoint interface provides some methods like
§ getArgs()
§ getThis() returns the proxy object
§ getTarget()
§ getSignature()
§ toString() – prints a useful description of the method being advised

Passing parameters to advice


@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
	// ...
}

Another way

@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
private void accountDataAccessOperation(Account account) {}

@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
	// ...
}

Define the @Auditable annotation:


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
	AuditCode value();
}

Advice that matches the execution of @Auditable methods:
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
	AuditCode code = auditable.value();
	// ...
}

Determining argument names
○ Parameter names in pointcut expressions should match those used in advice and pointcut method signatures.

Parameter names are not available through Java reflection.
So Spring AOP uses the following strategies to determine parameter names:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s