Skip to content

使用 ProxyFactory 以编程方式创建 AOP 代理 (Creating AOP Proxies Programmatically with the ProxyFactory)

使用 Spring 以编程方式创建 AOP 代理非常容易。这让你可以脱离 Spring IoC 容器而独立使用 Spring AOP。

目标对象实现的接口会被自动代理。以下列表显示了如何为一个目标对象创建一个带有拦截器和 Advisor 的代理:

java
ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);
factory.addAdvice(myMethodInterceptor);
factory.addAdvisor(myAdvisor);
MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
kotlin
val factory = ProxyFactory(myBusinessInterfaceImpl)
factory.addAdvice(myMethodInterceptor)
factory.addAdvisor(myAdvisor)
val tb = factory.proxy as MyBusinessInterface

第一步是构造一个类型为 org.springframework.aop.framework.ProxyFactory 的对象。你可以像上面的例子那样传入一个目标对象来创建它,或者在备选构造函数中指定要代理的接口。

你可以添加通知(通知的一种特殊类型是拦截器)、Advisor 或两者兼而有之,并在 ProxyFactory 的生命周期内对其进行操作。如果你添加了一个 IntroductionInterceptionAroundAdvisor,可以使代理实现额外的接口(即“引入”功能)。

ProxyFactory 上还有一些便捷方法(继承自 AdvisedSupport),允许你添加其他通知类型,例如前置通知和异常通知。AdvisedSupportProxyFactoryProxyFactoryBean 的共同父类。

提示

在大多数应用程序中,将 AOP 代理创建与 IoC 框架集成是最佳实践。我们建议你遵循通用原则,尽量将配置从 Java 代码中剥离(即使用声明式 AOP)。


补充教学

1. ProxyFactory vs. ProxyFactoryBean

这是许多初学者混淆的地方:

  • ProxyFactory:纯编程式工具类。你直接在代码里 new 它,手动添加拦截器,最后调用 getProxy()。它不需要 Spring 容器。
  • ProxyFactoryBean:这是一个 FactoryBean。你通常在 XML 或 Java 配置类中定义它。它依赖 Spring 容器,并利用容器来查找通知和管理单例状态。

2. 什么时候应该使用 ProxyFactory?

既然官方推荐声明式 AOP,那 ProxyFactory 还有用吗?当然:

  • 单元测试:你想测试某个 Advice 是否生效,但不想启动整个繁杂的 Spring Context。
  • 编写框架/中间件:比如你正在写一个轻量级的 RPC 框架,需要动态给接口套一个拦截层,这时 ProxyFactory 是最直接的选择。
  • 极致动态需求:某些逻辑需要根据运行时极其复杂的条件来动态决定拦截哪些方法,注解可能表达不出来。

3. 底层配置进阶

因为 ProxyFactory 继承了 ProxyConfig,所以你可以通过代码精细控制代理行为:

java
ProxyFactory factory = new ProxyFactory(myService);
// 强制使用 CGLIB 代理类
factory.setProxyTargetClass(true);
// 将代理暴露到 ThreadLocal 中,以便 AopContext.currentProxy() 访问
factory.setExposeProxy(true);
// 冻结配置,防止生成的代理被强转为 Advised 接口后修改拦截器
factory.setFrozen(true);
kotlin
val factory = ProxyFactory(myService).apply {
    isProxyTargetClass = true
    isExposeProxy = true
    isFrozen = true
}

4. 万全之策:AdvisedSupport

如果你深入源码,会发现 AdvisedSupport 才是真正的大脑。它持有所有的 Advisor 列表、目标源(TargetSource)以及缓存的拦截器链。无论是编程式还是声明式代理,最终都是在操作这个对象。理解了 AdvisedSupport,你就掌握了 Spring AOP 的半个核心。

Based on Spring Framework.