However proxy can intercept only external method calls. Which means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual interception at runtime.
Thus, the following code will not function correctly.
@Override public Object methodA(String id) { return methodBase("a", id); }
@Override public Object methodB(String id) { return methodBase("b", id); }
}
AspectJ Load-Time Weaving
Spring provides a library named spring-aspects and AdviceMode.ASPECTJ which can be used as value of mode filed for @EnableCaching, @EnableTransactionManagement and @EnableAsync annotations to support AspectJ load-time weaving. But that is not enough, AspectJ load-time weaver is required to weave aspect for target class.
AspectJ Load-Time Weaver weave target class by transforming class file bytecode using a ClassFileTransformer named ClassPreProcessorAgentAdapter from aspectjweaver.jar. This transformation can be performed either at JVM level through Instrumentation interface or at per ClassLoader level. A method with signature similar to void addTransformer(ClassFileTransformer transformer) is required to apply the transformation in class loading phase, Instrumentation support this method natively, while not all class loaders support this.
Custom class loader to apply class file transformation
Due to the fact that loadTimeWeaver is a bean and classloading is happening at bean definition parsing phase which certainly happens before bean creation phase in same application context, thus @EnableLoadTimeWeaving should be enabled in a application context which is a ancestor of the application context where target class located in.
Instrumentation has a method void addTransformer(ClassFileTransformer transformer) which can be used to apply ApectJ’s class file transformer. There are two existing java libraries, aspectjweaver and spring-instrument, provide agents to obtain instance of Instrumentation.
AspectJ java agent to apply class file transformation
You start JVM with -javaagent:/path/aspectweaver-1.8.10.jar, then the AspectJ load-time weaver use META-INF/aop.xml files located on classpath to weaving aspect to target classes. You don’t need @EnableLoadTimeWeaving here.
Spring java agent to obtain Instrumentation instance for transformation
Differ from aspectjweaver, agent provided by spring-instrument does not apply AspectJ load-time weaving by itself, it only obtain a Instrumentation. loadTimeWeaver initiated by @EnableLoadTimeWeaving can use this Instrumentation instance to apply class file transformation.