Core Terminology
- Target: Object being enhanced
- Joinpoint: Method eligible for interception
- Pointcut: Method actually intercepted
- Advice
- Weaving: Process of applying advice to target
- Proxy: Enhanced object created after weaving
- Aspect: Combination of pointcut and advice
Implementation Mechanisms
- JDK Dynamic Proxy (for interface implementations)
- Cglib Dynamic Proxy (to non-interface classes)
Pointcut Expression Syntax
Format: execution("modifier return_type package.class.method(parameters) throws_exception")
| Component | Examples |
|---|---|
| Modifier | * (any), public, protected |
| Return Type | void, String, * |
| Package | com.example.dao, com.example.*.service, com.example.dao.. |
| Class | UserServiceImpl, User*, *Service, * |
| Method | saveData, *, *Data, save* |
| Parameters | () (none), (..) (any), (String, int) |
Advice Types
@Aspect
@Component
public class AspectHandler {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
@Before("serviceMethods()")
public void beforeExecution(JoinPoint joinPoint) {
System.out.println("Pre-execution advice");
}
@AfterReturning(value = "serviceMethods()", returning = "result")
public void afterSuccess(JoinPoint joinPoint, Object result) {
System.out.println("Post-execution result: " + result);
}
@Around("serviceMethods()")
public Object wrapExecution(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Around advice - pre");
Object output = pjp.proceed();
System.out.println("Around advice - post");
return output;
}
@AfterThrowing(value = "serviceMethods()", throwing = "ex")
public void onFailure(Throwable ex) {
System.out.println("Exception handler: " + ex.getMessage());
}
@After("serviceMethods()")
public void finalizeOperation() {
System.out.println("Finalization advice");
}
}
Execution Order in Multiple Aspects
Use @Order(value) to define sequence where lower values have higher priority
Alternative Pointcut Expressions
within: Class-level matchingargs: Paramter-based matchingthis/target: Proxy/target type matching@within: Annotation on class@annotation: Annotation on method@args: Annotation on method parameters
Interface Annotation Interception Solution
public class AnnotationPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class> targetClass) {
return AnnotationUtils.findAnnotation(method, CustomAnnotation.class) != null;
}
}
public class AnnotationInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long start = System.currentTimeMillis();
try {
return invocation.proceed();
} finally {
System.out.println("Execution time: " + (System.currentTimeMillis() - start));
}
}
}
public class AnnotationAdvisor extends AbstractBeanFactoryPointcutAdvisor {
private Pointcut customPointcut;
@Override
public Pointcut getPointcut() {
return customPointcut;
}
}
@Configuration
public class AopConfig {
@Bean
public AnnotationAdvisor annotationAdvisor() {
AnnotationAdvisor advisor = new AnnotationAdvisor();
advisor.setCustomPointcut(new AnnotationPointcut());
advisor.setAdvice(new AnnotationInterceptor());
return advisor;
}
}