Understanding AOP: Interface Design, Joinpoint, and Weaving Mechanisms
This article explains the background of Aspect‑Oriented Programming, how to identify and describe join points through interface design, the structure of the AOP Alliance Joinpoint API, and the static and dynamic weaving techniques used by frameworks such as Spring.
Learning module design starts with interface design, which reveals how a module is implemented; once the interfaces are known, implementation becomes straightforward.
The motivation for AOP arises from OOP drawbacks: when many unrelated classes need the same cross‑cutting behavior (e.g., logging, security), duplicating code makes maintenance hard, so AOP adds a horizontal programming dimension.
AOP focuses on three processes: locating the pointcut, defining the cross‑cutting logic (advice), and weaving that logic into the target code.
Identifying pointcuts involves determining where in the program the cross‑cutting logic should be applied, such as fields, constructors, object methods, static methods, and reflective accesses.
Example Java code illustrates these elements:
public class Test {
public static void main(String[] args) {
// @1
B b = new B();
// @2
b.method();
// @3
B.say();
}
static class B {
// field
// @4
private String name;
// constructor
public B() {
// @1.1
}
// object method
public void method() {
// @2.2
}
// static method
static void say() {
// @3.3
}
}
}Join points can be classified into two major categories—fields and methods (including constructors, instance methods, and static methods). For object‑level join points, the interface must return both the AccessibleObject and the target instance; for class‑level join points, only the AccessibleObject is needed.
Another interface responsibility is to decide whether a join point should manage multiple advice executions, which can be implemented via a chain‑of‑responsibility pattern (e.g., Tomcat filters or Netty handlers). The AOP Alliance defines a Joinpoint interface for this purpose:
public interface Joinpoint {
Object proceed() throws Throwable;
Object getThis();
AccessibleObject getStaticPart();
}The methods mean:
Object proceed() – invoke the next advice in the chain.
Object getThis() – return the current target object (null for static join points).
AccessibleObject getStaticPart() – return the reflective object representing the join point (e.g., a Method instance).
Extensions of the join‑point interface can provide specialized sub‑interfaces for constructors, methods, or fields, though the AOP Alliance only defines method‑level join points.
Goal 2 addresses the abstraction of advice: advice needs join‑point information to apply enhancements. The AOP Alliance uses an MethodInterceptor with the signature:
Object invoke(MethodInvocation invocation) throws Throwable;Goal 3 covers weaving. Static weaving modifies bytecode during class loading via a custom class loader, while dynamic weaving uses techniques such as JDK proxies or CGLIB bytecode generation. Spring AOP employs dynamic weaving, creating proxy objects that hold a list of interceptors and apply advice when target methods are invoked.
Overall, Spring’s AOP implementation follows the AOP Alliance’s minimal set of interfaces, as illustrated by the accompanying diagrams (pointcut, joinpoint, advice, and weaving flow).
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.