- Aspect
- Combination of advice and pointcuts.
- Advice
- The implementation of functionality that will be applied.
- Pointcut
- A rule for matching the parts of the object model that the functionality will be applied to.
Enable annotation
<aop:aspectj-autoproxy />
Aspect
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect {
}
Pointcut
@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature
Combining pointcut expressions
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
@Aspect
public class BeforeAspect {
@Pointcut("execution(* com.apress.prospring2.ch06.services.*.*(..))")
private void serviceExecution() { }
@Pointcut(
"execution(* com.apress.prospring2.ch06.services.UserService.login(..))")
private void loginExecution() { }
@Before("serviceExecution() && !loginExecution()")
public void beforeLogin() throws Throwable {
if (SecurityContext.getCurrentUser() == null)
throw new RuntimeException("Must login to call this method.");
}
}
Sharing common pointcut definitions
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() {}
/**
* A join point is in the service layer if the method is defined
* in a type in the com.xyz.someapp.service package or any sub-package
* under that.
*/
@Pointcut("within(com.xyz.someapp.service..*)")
public void inServiceLayer() {}
/**
* A join point is in the data access layer if the method is defined
* in a type in the com.xyz.someapp.dao package or any sub-package
* under that.
*/
@Pointcut("within(com.xyz.someapp.dao..*)")
public void inDataAccessLayer() {}
/**
* 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 you 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)". (This assumes that you have
* named your Spring service beans in a consistent fashion.)
*/
@Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
public void businessService() {}
/**
* A data access operation is the execution of any method defined on a
* dao interface. This definition assumes that interfaces are placed in the
* "dao" package, and that implementation types are in sub-packages.
*/
@Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
public void dataAccessOperation() {}
}
Examples of common pointcut expressions
- execution(public * *(..))
- the execution of any public method
- execution(* set*(..))
- the execution of any method with a name beginning with "set"
- execution(* com.xyz.service.AccountService.*(..))
- the execution of any method defined by the AccountService interface
- execution(* com.xyz.service.*.*(..))
- he execution of any method defined in the service package
- execution(* com.xyz.service..*.*(..))
- the execution of any method defined in the service package or a sub-package
- within(com.xyz.service.*)
- any join point (method execution only in Spring AOP) within the service package
- within(com.xyz.service.*)
- any join point (method execution only in Spring AOP) within the service package
- within(com.xyz.service..*)
- any join point (method execution only in Spring AOP) within the service package or a sub-package
- this(com.xyz.service.AccountService)
- any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface
- target(com.xyz.service.AccountService)
- any join point (method execution only in Spring AOP) where the target object implements the AccountService interface
- args(java.io.Serializable)
- any join point (method execution only in Spring AOP) which takes a single parameter, and where the argument passed at runtime is Serializable
- @target(org.springframework.transaction.annotation.Transactional)
- any join point (method execution only in Spring AOP) where the target object has an @Transactional annotation
- @annotation(org.springframework.transaction.annotation.Transactional)
- any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation
- @args(com.xyz.security.Classified)
- any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the @Classified annotation
- bean(tradeService
- any join point (method execution only in Spring AOP) on a Spring bean named 'tradeService'
- bean(*Service)
- any join point (method execution only in Spring AOP) on Spring beans having names that match the wildcard expression '*Service'
Advice
As parameter of advice method you can use org.aspectj.lang.JoinPoint. Class which implements this interface have method: getTarget(), getArgs(), getSignature(), getThis(). You can use this method in advice. For example see @After advice.
Advice with reference to pointcut
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() {
// ...
}
}
Advice with in-place pointcut
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("execution(* com.xyz.myapp.dao.*.*(..))")
public void doAccessCheck() {
// ...
}
}
After returning advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
}
After throwing advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
@Aspect
public class AfterThrowingExample {
@AfterThrowing(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing="ex")
public void doRecoveryActions(DataAccessException ex) {
// ...
}
}
After (finally) advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
@Aspect
public class AfterFinallyExample {
@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doReleaseLock( JoinPoint jp ) {
// ...
Object[] targetMethodArgs = jp.getArgs();
//...
}
}
Around advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Passing parameters to advice
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" +
"args(account,..)")
public void validateAccount(Account account) {
// ...
}
@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" +
"args(account,..)")
private void accountDataAccessOperation(Account account) {}
@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
// ...
}
@Before(
value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
public void audit(JoinPoint jp, Object bean, Auditable auditable) {
AuditCode code = auditable.value();
// ... use code, bean, and jp
}
Thanks!
ReplyDeleteThis is example that i am looking for. Was stuck with Around advices, realized that Before advices was the one that i should use. Thanks
ReplyDeleteThank you very much. I try to find how to use the reference pointcus a day. You save a day for me.
ReplyDelete