Understanding AOP: AspectJ Compile‑Time Weaving vs Spring AOP Dynamic Proxies
This article explains Aspect‑Oriented Programming, compares AspectJ's compile‑time static weaving with Spring AOP's runtime dynamic proxies (JDK and CGLIB), and demonstrates both approaches through complete Java code examples and execution results.
AOP (Aspect‑Oriented Programming) supplements OOP by handling cross‑cutting concerns such as transactions, logging, and caching, and is implemented via proxies that can be static (compile‑time) or dynamic (runtime).
Using AspectJ for compile‑time enhancement
AspectJ creates static proxies during compilation, weaving aspects directly into the bytecode.
public class Hello {
public void sayHello() {
System.out.println("hello");
}
public static void main(String[] args) {
Hello h = new Hello();
h.sayHello();
}
}Aspect definition:
public aspect TxAspect {
void around(): call(void Hello.sayHello()) {
System.out.println("开始事务 ...");
proceed();
System.out.println("事务结束 ...");
}
}Compile with ajc -d . Hello.java TxAspect.aj and run Hello, producing:
开始事务 ...
hello
事务结束 ...The compiled Hello.class now contains additional methods generated by AspectJ, illustrating static weaving.
Using Spring AOP
Spring AOP employs dynamic proxies: JDK proxies for classes implementing interfaces and CGLIB proxies for concrete classes.
Interface and implementation example:
public interface Person {
String sayHello(String name);
}
@Component
public class Chinese implements Person {
@Timer
@Override
public String sayHello(String name) {
System.out.println("-- sayHello() --");
return name + " hello, AOP";
}
public void eat(String food) {
System.out.println("我正在吃:" + food);
}
}Aspect definition:
@Aspect
@Component
public class AdviceTest {
@Pointcut("@annotation(com.listenzhangbin.aop.Timer)")
public void pointcut() {}
@Before("pointcut()")
public void before() {
System.out.println("before");
}
}Spring Boot test shows JDK proxy output:
before
-- sayHello() --
class com.sun.proxy.$Proxy53When the target class does not implement an interface, Spring falls back to CGLIB:
@Component
public class Chinese {
@Timer
public String sayHello(String name) {
System.out.println("-- sayHello() --");
return name + " hello, AOP";
}
public void eat(String food) {
System.out.println("我正在吃:" + food);
}
}Running the same test now yields a CGLIB‑enhanced class:
before
-- sayHello() --
class com.listenzhangbin.aop.Chinese$EnhancerBySpringCGLIB$$56b89168Summary
AspectJ weaves aspects at compile time, offering better performance but requiring a special compiler, whereas Spring AOP creates proxies at runtime, needing no extra compilation step; the choice depends on performance requirements and build constraints.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
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.
