AOP底层实现关键的源码、方法解析
一、介绍
AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的核心特性之一,它通过代理机制实现了横切关注点的模块化。理解 AOP 的底层实现原理,对于深入掌握 Spring 框架和编写高质量代码至关重要。
本文将从源码层面深入解析 AOP 的实现机制,重点关注:
- 反射技术在 AOP 中的关键应用
- 代理对象的创建时机和动态代理类的生成阶段
- 基于 AOP 注解生命周期的完整执行流程
二、AOP 核心概念与架构
2.1 AOP 实现方式
Spring AOP 支持两种代理方式:
- JDK 动态代理 :基于接口实现,使用
java.lang.reflect.Proxy和InvocationHandler - CGLIB 代理:基于类继承实现,通过字节码增强技术生成子类
2.2 核心组件
- Aspect:切面,包含多个切点和通知
- Pointcut:切点,定义在哪些方法上应用通知
- Advice:通知,定义在切点处执行的逻辑(@Before、@After、@Around 等)
- Proxy:代理对象,AOP 的核心实现载体
三、反射技术在 AOP 中的关键应用
3.1 反射获取方法元信息
AOP 在扫描和匹配切点时,大量使用反射技术获取方法的元信息。
3.1.1 Method 反射获取
java
// Spring AOP 源码中的关键反射调用
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
// 获取方法注解
Annotation[] annotations = method.getAnnotations();
// 获取方法参数类型
Class<?>[] parameterTypes = method.getParameterTypes();
// 获取方法返回类型
Class<?> returnType = method.getReturnType();
// 获取方法名称
String methodName = method.getName();
}
反射技术要点:
getDeclaredMethods():获取类中声明的所有方法(包括私有方法)getAnnotations():获取方法上的所有注解getParameterTypes():获取方法参数类型数组getReturnType():获取方法返回类型
3.1.2 注解反射解析
java
// AspectJ 注解解析中的反射应用
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
// 通过反射获取目标方法信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
}
}
反射在注解解析中的作用:
- 扫描
@Aspect注解标记的类 - 解析
@Before、@After、@Around等通知注解 - 提取切点表达式(
execution、@annotation等) - 构建切点匹配器(
Pointcut)
3.2 反射调用目标方法
在代理对象执行时,需要通过反射调用原始目标方法。
3.2.1 JDK 动态代理中的反射调用
java
// JDK 动态代理 InvocationHandler 实现
public class JdkDynamicAopProxy implements InvocationHandler {
private final AdvisedSupport advised;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1. 通过反射获取目标对象
Object target = getTarget();
// 2. 获取方法拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
// 3. 构建方法调用对象(MethodInvocation)
MethodInvocation invocation = new ReflectiveMethodInvocation(
proxy, target, method, args, target.getClass(), chain);
// 4. 执行拦截器链
return invocation.proceed();
}
}
反射关键点:
Method.invoke(target, args):通过反射调用目标方法method.getParameterTypes():获取参数类型用于方法匹配method.getReturnType():获取返回类型用于返回值处理
3.2.2 CGLIB 代理中的反射调用
java
// CGLIB MethodInterceptor 实现
public class CglibAopProxy implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 1. 获取目标对象(通过反射)
Object target = getTarget();
// 2. 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
// 3. 构建方法调用
CglibMethodInvocation invocation = new CglibMethodInvocation(
proxy, target, method, args, target.getClass(), chain);
// 4. 执行拦截器链
return invocation.proceed();
}
}
CGLIB 反射应用:
- CGLIB 通过
MethodProxy.invoke()或MethodProxy.invokeSuper()调用方法 - 底层仍依赖反射机制获取方法元信息
- 使用 ASM 字节码技术生成代理类,但方法调用仍需反射
3.3 反射在切点匹配中的应用
java
// Pointcut 匹配器中的反射应用
public class AspectJExpressionPointcut implements Pointcut {
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 1. 通过反射获取方法签名信息
String methodName = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
Class<?> returnType = method.getReturnType();
// 2. 获取方法注解(反射)
Annotation[] annotations = method.getAnnotations();
// 3. 匹配切点表达式
return pointcutExpression.matches(method, targetClass);
}
}
四、AOP 代理对象的创建时机
4.1 BeanPostProcessor 机制
Spring AOP 的代理对象创建依赖于 BeanPostProcessor 机制,核心类是 AbstractAutoProxyCreator。
4.1.1 BeanPostProcessor 执行时机
java
// AbstractApplicationContext.refresh() 方法中的关键流程
public void refresh() throws BeansException {
// 1. 注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 2. 初始化单例 Bean
finishBeanFactoryInitialization(beanFactory);
}
执行顺序:
- Bean 定义加载阶段 :扫描
@Aspect注解,注册切面 Bean - BeanPostProcessor 注册阶段 :注册
AnnotationAwareAspectJAutoProxyCreator - Bean 实例化阶段 :每个 Bean 创建时都会经过
BeanPostProcessor.postProcessAfterInitialization()
4.1.2 AbstractAutoProxyCreator 核心逻辑
java
// AbstractAutoProxyCreator.postProcessAfterInitialization()
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断是否需要创建代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 如果已经处理过,直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 2. 如果不需要增强,直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 3. 如果是基础设施类,不需要代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 4. 获取增强器(Advisor)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5. 如果找到增强器,创建代理对象
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
关键时机点:
- Bean 初始化完成后 :
postProcessAfterInitialization()方法执行 - 切面扫描完成后 :所有
@Aspect类已注册为 Bean - 增强器匹配阶段 :
getAdvicesAndAdvisorsForBean()匹配切点
4.2 @EnableAspectJAutoProxy 注解的作用
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
核心作用:
- 导入
AspectJAutoProxyRegistrar,注册AnnotationAwareAspectJAutoProxyCreatorBean proxyTargetClass=true:强制使用 CGLIB 代理exposeProxy=true:暴露代理对象到 AopContext
4.2.1 AspectJAutoProxyRegistrar 注册逻辑
java
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册 AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 解析 @EnableAspectJAutoProxy 注解属性
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(
importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
五、动态代理类生成的阶段
5.1 JDK 动态代理类生成
5.1.1 Proxy.newProxyInstance() 源码分析
java
// java.lang.reflect.Proxy.newProxyInstance()
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
// 1. 验证 InvocationHandler 非空
Objects.requireNonNull(h);
// 2. 获取代理类 Class 对象(关键:动态生成代理类)
Class<?> cl = getProxyClass0(loader, intfs);
// 3. 通过反射获取构造函数
final Constructor<?> cons = cl.getConstructor(constructorParams);
// 4. 创建代理实例
return cons.newInstance(new Object[]{h});
}
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
// 1. 接口数量限制检查
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 2. 从缓存中获取或生成代理类
return proxyClassCache.get(loader, interfaces);
}
代理类生成时机:
- 首次调用时 :
Proxy.newProxyInstance()首次调用时生成代理类 - 类加载阶段 :通过
ProxyClassFactory生成代理类的字节码 - 缓存机制:生成的代理类会被缓存,后续直接使用
5.1.2 代理类字节码生成
java
// ProxyClassFactory.apply() 方法(简化版)
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
// 1. 生成代理类名称:$Proxy0, $Proxy1, ...
String proxyName = proxyPkg + proxyClassNamePrefix + num++;
// 2. 生成代理类字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
// 3. 通过 ClassLoader 加载代理类
return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
}
}
生成的代理类特点:
- 实现所有目标接口
- 所有方法调用都转发给
InvocationHandler.invoke() - 包含
equals()、hashCode()、toString()等方法的代理实现
5.2 CGLIB 代理类生成
5.2.1 Enhancer 创建代理类
java
// CGLIB Enhancer 创建代理对象
public class CglibAopProxy implements AopProxy {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class<?> rootClass = this.advised.getTargetClass();
Class<?> proxySuperClass = rootClass;
// 1. 创建 Enhancer
Enhancer enhancer = createEnhancer();
// 2. 设置父类(目标类)
enhancer.setSuperclass(proxySuperClass);
// 3. 设置接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
// 4. 设置回调(MethodInterceptor)
enhancer.setCallback(new DynamicAdvisedInterceptor(this.advised));
// 5. 生成代理类并创建实例
return createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass", ex);
}
}
}
CGLIB 代理类生成时机:
- Bean 创建时 :
createProxy()方法调用时 - 字节码生成阶段:使用 ASM 框架生成子类字节码
- 类加载阶段 :通过
ClassLoader.defineClass()加载生成的类
5.2.2 CGLIB 代理类特点
java
// CGLIB 生成的代理类结构(简化)
public class UserService$$EnhancerBySpringCGLIB$$xxx extends UserService {
private MethodInterceptor CGLIB$CALLBACK_0;
@Override
public void saveUser(User user) {
// 调用拦截器
MethodInterceptor interceptor = this.CGLIB$CALLBACK_0;
if (interceptor != null) {
interceptor.intercept(this,
CGLIB$saveUser$0$Method,
new Object[]{user},
CGLIB$saveUser$0$Proxy);
} else {
super.saveUser(user);
}
}
}
CGLIB 代理特点:
- 继承目标类,重写所有非 final 方法
- 使用
MethodInterceptor拦截方法调用 - 通过
MethodProxy实现高效的方法调用
5.3 代理方式选择逻辑
java
// DefaultAopProxyFactory.createAopProxy()
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 1. 判断是否强制使用 CGLIB
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class");
}
// 2. 目标类是接口,使用 JDK 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 3. 使用 CGLIB 代理
return new ObjenesisCglibAopProxy(config);
} else {
// 4. 有接口,使用 JDK 代理
return new JdkDynamicAopProxy(config);
}
}
选择规则:
- 有接口且未强制 CGLIB:使用 JDK 动态代理
- 无接口或强制 CGLIB:使用 CGLIB 代理
- 目标类是接口:使用 JDK 动态代理
六、基于 AOP 注解生命周期的完整执行流程
时序图:
markdown
1. Spring 容器启动
↓
2. @EnableAspectJAutoProxy 注册 AnnotationAwareAspectJAutoProxyCreator
↓
3. 扫描 @Aspect 注解的类,注册为 Bean
↓
4. 解析切面中的通知方法,构建 Advisor 列表
↓
5. 目标 Bean 实例化
↓
6. BeanPostProcessor.postProcessAfterInitialization() 执行
↓
7. 匹配增强器(通过反射匹配方法)
↓
8. 创建代理对象(JDK 或 CGLIB)
↓
9. 代理对象替换原始 Bean
↓
10. 方法调用时,代理对象拦截
↓
11. 构建拦截器链
↓
12. 按顺序执行拦截器(@Around → @Before → 目标方法 → @AfterReturning/@AfterThrowing → @After)
↓
13. 通过反射调用目标方法
↓
14. 返回结果
6.1 阶段一:配置类扫描与注册(@EnableAspectJAutoProxy)
6.1.1 配置类加载
java
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example")
public class AppConfig {
}
执行流程:
- Spring 容器启动 :
ApplicationContext初始化 - 配置类解析 :
ConfigurationClassPostProcessor处理@Configuration注解 - 注解导入 :
@EnableAspectJAutoProxy触发AspectJAutoProxyRegistrar注册
6.1.2 AspectJAutoProxyCreator 注册
java
// AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册 AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
关键点:
AnnotationAwareAspectJAutoProxyCreator继承AbstractAutoProxyCreator- 实现了
BeanPostProcessor接口 - 在 Bean 初始化后处理阶段创建代理对象
6.2 阶段二:切面类扫描与解析(@Aspect)
6.2.1 切面类扫描
java
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}
扫描流程:
- 组件扫描 :
@ComponentScan扫描@Aspect注解的类 - Bean 定义注册:将切面类注册为 Spring Bean
- 切面解析 :
AnnotationAwareAspectJAutoProxyCreator解析切面信息
6.2.2 切面元数据提取
java
// BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
List<String> beanNames = new ArrayList<>();
// 1. 获取所有 Bean 名称
for (String beanName : beanNames) {
// 2. 判断是否是切面类(通过反射检查 @Aspect 注解)
if (isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 3. 解析切面中的通知方法(通过反射获取方法注解)
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
advisors.addAll(classAdvisors);
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
反射技术应用:
Class.isAnnotationPresent(Aspect.class):检查类是否有@Aspect注解Method.getAnnotations():获取方法上的所有注解Method.getParameterTypes():解析通知方法参数类型
6.3 阶段三:增强器(Advisor)构建
6.3.1 通知方法解析
java
// ReflectiveAspectJAdvisorFactory.getAdvisors()
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 1. 通过反射获取所有方法
Method[] methods = aspectClass.getDeclaredMethods();
List<Advisor> advisors = new ArrayList<>();
for (Method method : methods) {
// 2. 解析通知注解(@Before、@After、@Around 等)
Advisor advisor = getAdvisor(method, aspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
6.3.2 切点表达式解析
java
// AbstractAspectJAdvisorFactory.getPointcut()
protected AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 1. 通过反射获取方法上的注解
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 2. 提取切点表达式
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(
candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
return ajexp;
}
反射关键操作:
Method.getAnnotation(Before.class):获取@Before注解Method.getAnnotation(After.class):获取@After注解Method.getAnnotation(Around.class):获取@Around注解- 通过反射读取注解属性值(如
value()、pointcut())
6.4 阶段四:目标 Bean 创建与代理对象生成
6.4.1 Bean 实例化
java
@Service
public class UserService {
public void saveUser(User user) {
// 业务逻辑
}
}
Bean 创建流程:
- 实例化 :通过反射创建 Bean 实例(
Constructor.newInstance()) - 属性注入:注入依赖的 Bean
- 初始化 :调用
@PostConstruct方法和InitializingBean.afterPropertiesSet() - 后处理 :执行
BeanPostProcessor.postProcessAfterInitialization()
6.4.2 代理对象创建
java
// AbstractAutoProxyCreator.wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 获取匹配的增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 2. 如果找到增强器,创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
return bean;
}
代理创建时机:
- Bean 初始化完成后 :
postProcessAfterInitialization()执行 - 增强器匹配成功 :找到匹配的
Advisor - 代理对象替换:返回代理对象替代原始 Bean
6.5 阶段五:方法调用与拦截器链执行
6.5.1 代理方法调用入口
java
// JdkDynamicAopProxy.invoke()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 1. 判断是否是 equals、hashCode 等基础方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass() != Advised.class) {
// 2. 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (targetClass != null ? targetClass : target.getClass());
// 3. 获取拦截器链(通过反射匹配方法)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 4. 如果拦截器链为空,直接调用目标方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 5. 构建方法调用对象,执行拦截器链
MethodInvocation invocation = new ReflectiveMethodInvocation(
proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
return retVal;
}
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
}
}
6.5.2 拦截器链执行
java
// ReflectiveMethodInvocation.proceed()
@Override
public Object proceed() throws Throwable {
// 1. 如果所有拦截器都执行完毕,调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 2. 获取下一个拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 3. 执行拦截器
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
return proceed();
}
} else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
protected Object invokeJoinpoint() throws Throwable {
// 通过反射调用目标方法
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
反射调用目标方法:
java
// AopUtils.invokeJoinpointUsingReflection()
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
6.6 阶段六:通知方法执行顺序
6.6.1 @Around 通知执行
java
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around before");
try {
// 调用目标方法(通过反射)
Object result = joinPoint.proceed();
System.out.println("Around after returning");
return result;
} catch (Exception e) {
System.out.println("Around after throwing");
throw e;
} finally {
System.out.println("Around after");
}
}
}
执行流程:
- @Around 前置逻辑 :执行
aroundMethod()方法的前半部分 - 调用目标方法 :
joinPoint.proceed()触发拦截器链继续执行 - @Around 后置逻辑:目标方法返回后执行后半部分
6.6.2 通知执行顺序
java
// 完整的通知执行顺序
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
// 1. @Before 执行
}
@After("execution(* com.example.service.*.*(..))")
public void afterMethod(JoinPoint joinPoint) {
// 4. @After 执行(无论是否异常)
}
@AfterReturning("execution(* com.example.service.*.*(..))")
public void afterReturning(JoinPoint joinPoint, Object result) {
// 3. @AfterReturning 执行(正常返回)
}
@AfterThrowing("execution(* com.example.service.*.*(..))")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
// 3. @AfterThrowing 执行(异常抛出)
}
@Around("execution(* com.example.service.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
// 0. @Around 前置
try {
Object result = joinPoint.proceed(); // 调用目标方法
// 2. @Around 后置(正常返回)
return result;
} catch (Throwable e) {
// 2. @Around 后置(异常)
throw e;
}
}
}
执行顺序:
- @Around 前置 → @Before → 目标方法 → @AfterReturning/@AfterThrowing → @After → @Around 后置
6.6.3 拦截器链构建
java
// DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 1. 通过反射匹配切点
if (pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass) &&
pointcutAdvisor.getPointcut().getMethodMatcher().matches(method, actualClass)) {
// 2. 获取拦截器
MethodInterceptor interceptor = (MethodInterceptor) advisor.getAdvice();
interceptorList.add(interceptor);
}
}
}
return interceptorList;
}
反射匹配关键点:
MethodMatcher.matches(method, targetClass):通过反射获取方法信息进行匹配ClassFilter.matches(actualClass):通过反射检查类信息
七、AOP 底层实现的关键技术总结
7.1 反射技术的核心应用
-
注解扫描与解析:
Class.getAnnotation():获取类注解Method.getAnnotation():获取方法注解Method.getParameterTypes():获取参数类型
-
方法调用:
Method.invoke(target, args):反射调用目标方法ReflectionUtils.makeAccessible():设置方法可访问
-
元数据获取:
Class.getDeclaredMethods():获取类中所有方法Method.getReturnType():获取返回类型Method.getName():获取方法名
7.2 代理对象创建时机总结
- 配置阶段 :
@EnableAspectJAutoProxy注册AnnotationAwareAspectJAutoProxyCreator - 切面扫描阶段 :扫描
@Aspect注解的类,构建Advisor - Bean 创建阶段 :每个 Bean 初始化完成后,通过
BeanPostProcessor检查是否需要代理 - 代理生成阶段:匹配到增强器后,创建 JDK 或 CGLIB 代理对象
7.3 动态代理类生成阶段
-
JDK 动态代理:
- 生成时机:
Proxy.newProxyInstance()调用时 - 生成方式:
ProxyGenerator.generateProxyClass()生成字节码 - 类加载:通过
ClassLoader.defineClass()加载
- 生成时机:
-
CGLIB 代理:
- 生成时机:
Enhancer.create()调用时 - 生成方式:ASM 框架生成子类字节码
- 类加载:通过
ClassLoader.defineClass()加载
- 生成时机: