AOP Concept
- Join Point
- A point in execution of a program such as a method call or field assignment
- Pointcut
- An expression that selects on or more Join Points
- Advice
- Code to be executed at a Join Point that has been selected by a Pointcut
- Aspect
- A module that encapsulates pointcuts and advice
Defining pointcuts
- Spring AOP uses AspectJ’s pointcut expression language
- Spring AOP supports only method execution joinpoints
- Common pointcut designator
- execution(
)
- execution(
- Can be chained together to create composite
- && (and), || (or), ! (not)
- Method pattern
- [Modifiers] ReturnType [ClassType] MethodName ([Arguments]) [throws ExceptionType]
Pointcut expression:

Spring AOP Proxies
- Spring AOP uses standard J2SE dynamic proxies for interfaces
- It can also use CGLIB proxies to proxy classes

Supported Advices
-
Before Advice - @Before
- Advice is executed before method invocation
- If advice throws an exception, target will not be called
@Aspect public class MethodExecutionTracker { // track all setter methods @Before("execution(void set*(..))") public void trackMethod() { // log message before method is executed } } -
After returning Advice - @AfterReturning
- Advice is executed when a matched method execution returns normally
@Aspect public class MethodExecutionTracker { // track all setter methods @AfterReturning("execution(void set*(..))") public void trackMethod() { // log message after method is executed } }@Aspect public class MethodExecutionTracker { // track all getter methods @AfterReturning(value="execution(* get*(..))", returning=”retValue”) public void trackMethod(Object retValue) { // log retValue after method is executed } } -
After throwing Advice - @AfterThrowing
- Advice is executed when a matched method execution exits by throwing an exception
@Aspect public class MethodExecutionTracker { // track all setter methods @AfterThrowing(value="execution(void set*(..))", throwing=”ex”) public void trackException(LibraryException ex) { // log message after exception is thrown } } -
After (finally) Advice - @After
- Advice is executed when a matched method execution returns normally or it exits by throwing an exception
@Aspect public class MethodExecutionTracker { // track all update methods @After("execution(void update*(..))") public void trackMethod(LibraryException ex) { // log message after method is executed, or exception is thrown } } -
Around Advice - @Around
- Advice runs “around” a matched method execution
- It can do something before and after method execution
- You can skip the target execution
@Aspect public class MethodExecutionTracker { // track all update methods @Around("execution(void update*(..))") public Object trackMethod(ProceedingJoinPoint pjp) throws Throwable { // log message before method is executed Object retVal = pjp.proceed(); // log message after method is executed return retVal; } }
Named Pointcuts
- Try to break one complicated expression into several less complicates sub-expressions
- Allow pointcut expression reusability
- Consider externalizing expressions into dedicated class
- When you have many pointcuts
- When you have complicated expressions
public class SystemArchitecture {
@Pointcut("execution(void set*(..))")
public void setterMethod(){}
@Pointcut("execution(* get*(..))")
public void getterMethod(){}
}
@Aspect
public class MethodExecutionTracker {
// track all setter methods
@Before(“example.SystemArchitecture.setterMethod()”)
public void trackMethod() {
// log message
}
}
Context Selecting
- Pointcuts may select useful JoinPoint context
- The currently executed object
- The target object
- Method arguments
- Annotations associated with the method, target, or argument
- Allows for simple POJO advice methods
- Alternative to working with a JoinPoint object directly
Example: Let’s log detail message every time there is new Customer going to be added.
public interface CustomerService {
void addCustomer(Customer c);
}
@Before(“execution(void *.service.CustomerService+.addCustomer(Customer))
&& target(service) && args(cust)”)
public void logNewCustomer(CustomerService service, Customer cust){
// use service and cust to log details
}
// Usage of named pointcut with contectual arguments 'service' and 'cust'
@Before(“addCustomerMethod(service,cust)”)
public void logNewCustomer(CustomerService service, Customer cust){
// use service and cust to log details
}
// Named Pointcut definition (method name = pointcut name)
@Pointcut(“execution(void *.service.CustomerService+.addCustomer(Customer))
&& target(service) && args(cust)”)
public void addCustomerMethod(CustomerService service, Customer cust){}
Pointcut Expression with Annotation
-
Selecting any method returning void and annotated with the @Transactional
execution( @org.springframework.transaction.annotation.Transactional void *(..) ) -
Select any method that returns a value annotated with the @Tracked
execution( (@example.Tracked *) *(..) ) -
Run security check before any @Secured service operation (annotation() designator)
@Before(“execution(* service..*.*(..)) && target(object) && @annotation((secured)”) public void check(JoinPoint jp, Object object, Secured secured){ checkPermission(jp,object,secured.allowedRoles()); }
Limitations
- Can only advise public Join Points
- Can only apply aspects to Spring beans
- Limitations of weaving with proxies
- Spring will add behavior using dynamic proxies if a JoinPoint is declared on an interface
- If JoinPoint is in class without an interface, Spring will use CGLIB for weaving
- When using proxies, if method a() calls method b() on the same class/interface. Advice will never be executed for method b()