Deep Dive into Spring AOP: Core Classes, Proxy Mechanics, and Source Code Walkthrough
This article provides a comprehensive analysis of Spring AOP, covering its core classes, multiple proxy mechanisms, annotation‑based configuration in Spring Boot, the differences between Spring Boot 1.x and 2.x AOP settings, and detailed source‑code snippets that illustrate how advisors, pointcuts, and advices are created and applied.
Aspect‑Oriented Programming (AOP) is essential in the Spring framework for implementing transactions, caching, security and other cross‑cutting concerns. This article performs an in‑depth source‑code analysis of Spring AOP and its usage in Spring Boot. Spring AOP – core classes related to various proxy mechanisms. Spring Boot – source analysis of the annotation‑based AOP configuration.
Differences between Spring Boot 1.x and 2.x AOP default settings.
Part 1: Core Classes of Spring AOP Proxy Mechanisms
Spring AOP defines three fundamental concepts: advisorCreator – abstract class representing the proxy creation mechanism. Implementations of AbstractAutoProxyCreator correspond to specific proxy strategies. It extends BeanPostProcessor to scan and obtain advisors. advisor – the concrete representation of a Spring AOP aspect, encapsulating a pointcut and its associated advice. advice – the method that implements the actual enhancement (e.g., before, after, around).
UML diagram of advisorCreator:
AbstractAutoProxyCreator– the core abstract class exposed by Spring AOP. BeanNameAutoProxyCreator – creates proxies based on bean names (used by frameworks such as Druid). AbstractAdvisorAutoProxyCreator – scans all Advisor implementations and is more flexible than name‑matching. DefaultAdvisorAutoProxyCreator – default implementation of AbstractAdvisorAutoProxyCreator. AspectJAwareAdvisorAutoProxyCreator – the common implementation for AspectJ; its subclass AnnotationAwareAspectJAutoProxyCreator is used when annotations are enabled. AnnotationAwareAspectJAutoProxyCreator – the most widely used AOP creator; it scans for @Aspect classes and registers corresponding advisors automatically.
Advisor
UML diagram of advisor:
StaticMethodMatcherPointcut– static method matcher defining a classFilter and implementing StaticMethodMatcher to match methods. StaticMethodMatcherPointcutAdvisor – advisor for static method matching, extends ordering capabilities. NameMatchMethodPointcut – matches methods by name (supports fuzzy matching via mappedNames). NameMatchMethodPointcutAdvisor – advisor that wraps NameMatchMethodPointcut. RegexpMethodPointcutAdvisor – advisor based on regular‑expression pointcuts, uses JdkRegexpMethodPointcut for parsing. DefaultPointcutAdvisor – a flexible default advisor that can combine pointcuts and advice. InstantiationModelAwarePointcutAdvisorImpl – the most commonly used advisor in Spring Boot; it creates an @Aspect ‑based advisor for each method.
Advice
UML diagram of advice:
AspectJMethodBeforeAdvice– before advice corresponding to @Before. AspectJAfterReturningAdvice – after‑returning advice corresponding to @AfterReturning; optional returning attribute is handled. AspectJAroundAdvice – around advice corresponding to @Around, executed before and after the target method. AspectJAfterAdvice – after (finally) advice corresponding to @After, always executed regardless of exceptions.
All these implementations ultimately provide the same AOP functionality through different entry points.
Source code for a typical annotation‑based aspect in Spring Boot:
@Aspect
@Component
public class LogableAspect {
@Pointcut("@annotation(com.springboot2.spring5.springAop.aspect.Logable)")
public void aspect() {}
@Around("aspect()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
// ...
Object returnValue = point.proceed(point.getArgs());
// ...
return returnValue;
}
}In most projects this is the most common way to use AOP: an @Aspect class with @Around (or other) advice.
Part 2: Spring Boot AOP Annotation Source Analysis
The process consists of three main steps:
Create the AbstractAutoProxyCreator object.
Scan the container for aspects and create PointcutAdvisor objects.
Generate the proxy class.
Step 1: Create AbstractAutoProxyCreator
When the spring-boot-starter-aop dependency is present, Spring Boot automatically registers AnnotationAwareAspectJAutoProxyCreator via spring.factories and AopAutoConfiguration. The configuration class looks like:
# Auto Configure
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration, @Configuration
@ConditionalOnClass({EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class})
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {}
}The condition @ConditionalOnClass ensures the configuration is loaded only when the required AOP classes are on the classpath. The property spring.aop.auto defaults to true, so manual enabling with @EnableAspectJAutoProxy is unnecessary.
Step 2: Scan Container for Aspects and Create PointcutAdvisor
The AnnotationAwareAspectJAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor. During bean instantiation it checks whether a bean is an infrastructure class or should be skipped, then creates a proxy if a custom TargetSource is defined. The core method is:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// ... determine if bean can be proxied ...
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
return proxy;
}
return null;
}Advisor creation is performed by ReflectiveAspectJAdvisorFactory. For each method annotated with @Before, @After, @Around, etc., an InstantiationModelAwarePointcutAdvisorImpl is built:
public Advisor getAdvisor(Method method, MetadataAwareAspectInstanceFactory factory,
int order, String aspectName) {
AspectJExpressionPointcut pointcut = getPointcut(method, factory.getAspectMetadata().getAspectClass());
if (pointcut == null) return null;
return new InstantiationModelAwarePointcutAdvisorImpl(pointcut, method, this,
factory, order, aspectName);
}The getAdvice method maps the annotation type to the concrete advice implementation (e.g., AspectJMethodBeforeAdvice, AspectJAfterReturningAdvice, etc.).
Step 3: Generate Proxy Class
After advisors are collected, wrapIfNecessary decides whether to create a JDK dynamic proxy or a CGLIB proxy based on the configuration flags optimize, proxyTargetClass, and whether user‑supplied interfaces exist:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors,
new SingletonTargetSource(bean));
proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}The actual proxy creation is delegated to AopProxyFactory.createAopProxy, which selects JdkDynamicAopProxy when only interfaces are present, otherwise ObjenesisCglibAopProxy (CGLIB) is used. The flag proxyTargetClass defaults to true in Spring Boot 2.x, meaning class‑based (CGLIB) proxies are the default.
Part 3: Spring Boot 1.x vs 2.x AOP Configuration Changes
In Spring Boot 1.5 the AopAutoConfiguration for CGLIB proxies is:
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class",
havingValue = "true", matchIfMissing = false)
public static class CglibAutoProxyConfiguration {}In Spring Boot 2.x the same configuration becomes:
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class",
havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {}The key change is that proxy-target-class now defaults to true, so class‑based (CGLIB) proxies are always used unless the developer explicitly configures interface‑based (JDK) proxies.
Summary
Spring Boot automatically enables AOP through AopAutoConfiguration. It registers AnnotationAwareAspectJAutoProxyCreator, which scans for @Aspect classes, creates Advisor objects, and, based on the proxy configuration, generates either JDK dynamic proxies or CGLIB proxies that are injected into the container.
GitHub repository with the complete demo code: https://github.com/admin801122/springboot2-spring5-studying
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.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
