Notes

Notes: Spring AOP: 2: Pointcuts

Ref: Spring documentation
Declaring A Pointcut
○ Pointcuts are collection of join-points.
○ Spring AOP only supports method execution join points for Spring beans. So pointcuts match only the execution of methods on Spring beans.
○ A pointcut declaration has two parts:
§ a signature comprising a name and any parameters,
§ a pointcut expression that determines exactly which method executions we are interested in.
○ In the @AspectJ annotation-style of AOP,
§ the pointcut signature is provided by a regular method definition,
§ the pointcut expression is indicated using the @Pointcut annotation
§ the method serving as the pointcut signature must have a void return type.
§ defining a pointcut named ‘anyOldTransfer’ that will match the execution of any method named ‘transfer’:

@Pointcut("execution(* transfer(..))")                 // the pointcut expression
			private void anyOldTransfer() {}            // the pointcut signature

Supported Pointcut Designators (PCDs) in Spring
execution – for matching method execution join points, this is the primary pointcut designator you will use when working with Spring AOP within – limits matching to join points
Within– limits matching to join points within certain types (simply the execution of a method declared within a matching type when using Spring AOP)
this – limits matching to join points where the bean reference (Spring AOP proxy) is an instance of the given type
target – limits matching to join points where the target object (application object being proxied) is an instance of the given type
args – limits matching to join points where the arguments are instances of the given types
@target – limits matching to join points where the class of the executing object has an annotation of the given type
@args – limits matching to join points where the runtime type of the actual arguments passed have annotations of the given type(s)
@within – limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP)
@annotation – limits matching to join points where the subject of the join point (method being executed in Spring AOP) has the given annotation

Since Spring AOP supports joinpoints only as the execution of methods, all the above designators act as further filtering criteria in addition to the execution of methods.

Additionally Spring supports its own PCD called ‘bean‘.
○ This PCD allows you to limit the matching of join points to a particular named Spring bean, or to a set of named Spring beans (when using wildcards)
○ Since wildcard (*) is supported, if we have some naming conventions for your Spring beans we can quite easily write a ‘bean’ PCD expression to pick them out.
○ This PCD is instance based (not type based)

All above PCDs can be &&’ed, ||’ed, and ! (negated) too.

Combining Pointcuts

@Pointcut("execution(public * *(..))")                                                //Matched against any public method
private void anyPublicOperation() {}

@Pointcut("within(com.xyz.someapp.trading..*)")    //execution of any public method in trading package
private void inTrading() {}

@Pointcut("anyPublicOperation() && inTrading()")                         //Above two combined
private void tradingOperation() {}

○ It is a best practice to build more complex pointcut expressions out of smaller named components as shown above.
○ When referring to pointcuts by name, normal Java visibility rules apply (you can see private pointcuts in the same type, protected pointcuts in the hierarchy, public pointcuts anywhere and so on). Visibility does not affect pointcut matching.

Any given pointcut is matched against public methods only.

For protected/private methods or constructors, consider the use of Spring-driven native AspectJ weaving (load time weaving) instead of Spring’s proxy-based AOP framework.

A well written pointcut should try and include at least the two types –kinded (execution, get, set, call, handler, etc )and scoping (within, withincode, etc) – whilst the contextual designators (ex- target, @annotation) may be included if wishing to match based on join point context, or bind that context for use in the advice.

Supplying either just a kinded designator or just a contextual designator will work but could affect weaving performance (time and memory used) due to all the extra processing and analysis.

Scoping designators are very fast to match and their usage means AspectJ can very quickly dismiss groups of join points that should not be further processed – that is why a good pointcut should always include one if possible.
***************************************************

Pointcut examples
“SystemArchitecture” aspect
○ Recommended approach – Define an aspect that captures common pointcut expressions for this purpose.

	package com.xyz.someapp;
	import org.aspectj.lang.annotation.Aspect;
	import org.aspectj.lang.annotation.Pointcut;
	
	@Aspect
	public class SystemArchitecture {
		
		/**
		* A join point is in the web layer if the method is defined 
		*in a type in the com.xyz.someapp.web package or 
		*any sub-package  under that. */
		@Pointcut("within(com.xyz.someapp.web..*)")
		public void inWebLayer() {}
		
		@Pointcut("within(com.xyz.someapp.service..*)")
		public void inServiceLayer() {}
		
		@Pointcut("within(com.xyz.someapp.dao..*)")
		public void inDataAccessLayer() {}
		
		@Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
		public void businessService() {}
	}
	

Notice that all the above pointcut methods are public and
so can be used anywhere.

A business service is the execution of any method defined on a service interface. This definition assumes that interfaces are placed in the “service” package, and that implementation types are in sub-packages.

If we group service interfaces by functional area (for example, in packages *com.xyz.someapp.abc.service and com.xyz.def.service) then the pointcut expression “execution(* com.xyz.someapp..service.*.*(..))” could be used instead.

Alternatively, you can write the expression using the ‘bean’ * PCD, like so “bean(*Service)”. (Useful when we name Spring service beans in a consistent fashion.)

The most often used PCD is execution. The format of expression is
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

The elements ret-type-pattern, name-pattern, param-pattern are mandatory.
○ We can use * on ret-type pattern and name-pattern
○ For param-pattern
§ () matches methods which take no arguments.
§ (..) indicates any number of parameters
§ (*) one or more arguments
§ (*, String) two arguments – first of any type, second of String type.

Some examples
○ any join point where the target object implements the AccountService interface:
§ target(com.xyz.service.AccountService)
○ any join point which takes a single parameter, and where the argument passed at runtime is Serializable
§ args(java.io.Serializable)
§ Note that the pointcut given above is different to execution(* *(java.io.Serializable)): the args version matches if the argument passed at runtime is Serializable, the execution version matches if the method signature declares a single parameter of type Serializable.

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