## AopProxyFactory - [AopProxyFactory](#aopproxyfactory) - [一、基本信息](#一基本信息) - [二、基本描述](#二基本描述) - [三、主要功能](#三主要功能) - [四、接口源码](#四接口源码) - [五、主要实现](#五主要实现) - [六、类关系图](#六类关系图) - [七、最佳实践](#七最佳实践) - [八、源码分析](#八源码分析) ### 一、基本信息 ✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading) ### 二、基本描述 `AopProxyFactory` 接口是 Spring AOP 框架的关键组件之一,负责根据配置信息创建 AOP 代理对象,支持根据目标对象的类型和配置选择合适的代理方式(JDK 动态代理或 CGLIB 代理)。 ### 三、主要功能 1. **创建 AOP 代理对象** + 根据传入的 `AdvisedSupport` 对象,利用指定的代理方式(JDK 动态代理或 CGLIB 代理)生成 AOP 代理对象。 2. **决定代理方式** + 根据目标类的类型和配置信息,确定是否使用 JDK 动态代理或 CGLIB 代理。这个决定通常是基于配置中的一些条件,例如是否需要代理接口或者是否允许使用 CGLIB 代理。 3. **支持灵活配置** + 通过实现该接口,可以灵活地定制 AOP 代理的生成方式,以满足不同场景下的需求。 ### 四、接口源码 `AopProxyFactory`接口 ,其功能是创建基于 `AdvisedSupport` 配置对象的 AOP 代理。代理对象需要满足一系列约定,包括实现被配置指示的所有接口、实现 `Advised` 接口、实现 `equals` 方法用于比较被代理的接口、通知和目标、并且在通知者和目标都是可序列化的情况下应该是可序列化的,以及在通知者和目标都是线程安全的情况下应该是线程安全的。该接口的实现应该能够根据给定的 AOP 配置创建相应的 AOP 代理对象,并在配置无效时抛出 `AopConfigException` 异常。 ```java /** * 接口,由能够基于 {@link AdvisedSupport} 配置对象创建 AOP 代理的工厂实现。 * *
代理对象应遵守以下约定: *
代理可能允许或不允许更改通知。如果它们不允许更改通知(例如,因为配置已被冻结),则代理应在尝试更改通知时抛出 {@link AopConfigException}。
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public interface AopProxyFactory {
/**
* 根据给定的 AOP 配置创建一个 {@link AopProxy}。
* @param config 以 AdvisedSupport 对象形式表示的 AOP 配置
* @return 相应的 AOP 代理
* @throws AopConfigException 如果配置无效
*/
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
```
### 五、主要实现
1. **DefaultAopProxyFactory**
+ `DefaultAopProxyFactory` 是 `AopProxyFactory` 接口的默认实现类,它负责根据给定的 `AdvisedSupport` 配置对象创建 AOP 代理,根据配置信息选择合适的代理方式(JDK 动态代理或 CGLIB 代理),并处理可能出现的异常情况,使得 Spring AOP 能够灵活地生成并使用 AOP 代理对象,实现切面编程的功能。
### 六、类关系图
~~~mermaid
classDiagram
direction BT
class AopProxyFactory {
< 如果对于给定的 {@link AdvisedSupport} 实例满足以下条件之一,则创建 CGLIB 代理:
* 通常情况下,可以通过指定 {@code proxyTargetClass} 来强制使用 CGLIB 代理,或者通过指定一个或多个接口来使用 JDK 动态代理。
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 2004-03-12
* @see AdvisedSupport#setOptimize
* @see AdvisedSupport#setProxyTargetClass
* @see AdvisedSupport#setInterfaces
*/
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 检查是否支持CGLIB代理,如果是,则创建CGLIB代理
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// 获取目标类
Class> targetClass = config.getTargetClass();
if (targetClass == null) {
// 如果目标类为空,则抛出AopConfigException异常
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代理
return new ObjenesisCglibAopProxy(config);
} else {
// 否则,创建JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
/**
* 确定提供的 {@link AdvisedSupport} 是否仅指定了 {@link org.springframework.aop.SpringProxy} 接口
* (或者根本没有指定代理接口)。
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
```
*
*
*