浅析Spring AOP 代理的生成机制
浅析Spring AOP 代理的生成机制
- 一、生成的核心时机:初始化后置处理
- 二、源码解析:关键类与流程
- 三、时序图:代理生成在容器初始化中的位置
- 四、总结:核心要点

一、生成的核心时机:初始化后置处理
AOP 代理的生成主要发生在以下两个阶段:
- 初始化前的提前代理(可选):通过
resolveBeforeInstantiation
方法尝试在 Bean 实例化前生成代理对象 - 初始化后的代理生成(主要):通过
postProcessAfterInitialization
方法在 Bean 初始化完成后生成代理对象
AOP 代理对象的生成时机主要集中在 Bean 初始化的后置处理阶段,具体通过 BeanPostProcessor
的扩展机制实现。
如果对BeanPostProcessor
感到陌生,可参考这篇文章:【Spring BeanPostProcessor:机制解读与代码实践】
二、源码解析:关键类与流程
核心后置处理器:AbstractAutoProxyCreator
该类实现了 BeanPostProcessor
接口,核心方法为 postProcessAfterInitialization
,用于在 Bean 初始化后生成代理。
源码如下:
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean != null) {// 生成用于缓存的键,基于 bean 类型和名称Object cacheKey = getCacheKey(bean.getClass(), beanName);// 检查是否已经在早期代理引用中处理过此 bean,避免重复创建代理或循环依赖问题if (!this.earlyProxyReferences.contains(cacheKey)) {// 【核心方法】:具体生成代理对象的逻辑return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;
}
其中 wrapIfNecessary
方法负责决定是否为给定的 bean 创建代理对象。下面是对该方法的详细分析:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (beanName != null && this.targetSourcedBeans.contains(beanName)) {return bean;}if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}// 检查 bean 是否为基础设施类(如 Advisor、Pointcut 等) 或者是否应该跳过代理创建(通过 shouldSkip 方法判断)if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// 获取适用于该 bean 的通知和切面Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);// 如果找到适用于该 bean 的通知或切面,则创建代理if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);// 【核心方法】创建代理对象。使用 SingletonTargetSource 封装原始 bean,作为代理的目标对象Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);// 返回原始 beanreturn bean;
}
其中createProxy
是真正创建代理对象的方法,下面是对该方法的详细分析:
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}// 创建代理工厂实例并复制当前配置ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);// 确定代理策略:JDK 动态代理(基于接口)或 CGLIB 代理(基于类)if (!proxyFactory.isProxyTargetClass()) {// 检查是否应该强制使用 CGLIB 代理if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {// 评估 bean 实现的接口,决定是否使用 JDK 动态代理evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}// 【核心方法】使用指定的类加载器创建并返回代理对象return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(ClassLoader classLoader) {return createAopProxy() // 【核心方法】生成代理工厂(内部有判断应该生成 “JDK动态代理” or “CGLIB代理” 的逻辑).getProxy(classLoader);
}
createAopProxy()
方法是 Spring AOP 框架中创建代理对象的核心工厂方法。它负责初始化代理创建环境并委派给实际的 AOP 代理工厂来生成代理实例。下面是对该方法的详细分析:
protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}// 获取 AopProxyFactory 并使用它创建 AopProxy 实例// 传入当前的 ProxyConfig 对象,包含了所有代理配置信息return getAopProxyFactory().createAopProxy(this);
}
这个 createAopProxy
方法是 Spring AOP 框架中 DefaultAopProxyFactory
类的核心实现,负责根据配置决定使用 JDK 动态代理还是 CGLIB 代理。下面是对该方法的详细分析:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 判断是否应该使用 CGLIB 代理的条件:// 1. optimize=true:是否需要优化代理创建过程// 2. proxyTargetClass=true:是否强制使用 CGLIB 代理// 3. hasNoUserSuppliedProxyInterfaces():目标类是否未实现任何接口if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}// 如果目标类是接口或已经是代理类,则使用 JDK 动态代理if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 其他情况(普通类且需要 CGLIB 代理),使用 ObjenesisCglibAopProxyreturn new ObjenesisCglibAopProxy(config);}else {// 如果不需要强制使用 CGLIB 代理且目标类实现了接口,则使用 JDK 动态代理return new JdkDynamicAopProxy(config);}
}
三、时序图:代理生成在容器初始化中的位置
四、总结:核心要点
- 时机:主要在 Bean 的
postProcessAfterInitialization
阶段生成代理,确保 Bean 完全初始化(如果存在循环引用/依赖,则会在实例化阶段提前处理AOP) - 代理类型:根据目标类是否为接口自动选择
JDK 动态代理
或CGLIB 代理
- 源码核心类:
AbstractAutoProxyCreator
(代理创建逻辑)、DefaultAopProxyFactory
(代理类型选择)。
通过上述流程,Spring 实现了对目标 Bean 的动态增强,完成 AOP 代理的创建与注入。