Spring使用ProxyFactoryBean创建代理对象

Spring使用ProxyFactoryBean创建代理对象,在Spring中创建AOP代理的基本方法是使用org.springframework.aop.framework.ProxyFactoryBean。这提供了对切入点、应用的任何通知及其顺序的完全控制。但是,如果你不需要这种控制,则有更简单的选项更可取。,和其他Spring FactoryBean实现一样,ProxyFactoryBean引入了一个间接层。如果定义了一个名为foo的ProxyFactoryBean,那么引用foo的对象不会看到ProxyFactoryBean实例本身,而是看到一个由ProxyFactoryBean中的getObject()方法实现创建的对象。此方法创建封装目标对象的AOP代理。,使用ProxyFactoryBean或另一个支持IoC的类来创建AOP代理的最重要的好处之一是,IoC也可以管理Advice和Pointcut。这是一个强大的特性,可以实现某些用其他AOP框架难以实现的方法。例如,通知本身可以引用应用程序对象(目标之外,它应该在任何AOP框架中可用),受益于依赖项注入提供的所有可插拔性。,和Spring提供的大多数FactoryBean实现一样,ProxyFactoryBean类本身就是一个JavaBean。它的属性用于:,ProxyFactoryBean特有的其他属性包括:,​ProxyFactoryBean如何选择为特定目标对象(要代理的对象)创建基于JDK的代理或基于CGLIB的代理的最终文档。,如果要代理的目标对象的类(以下简称为目标类)没有实现任何接口,则创建一个基于cglib的代理。这是最简单的场景,因为JDK代理是基于接口的,没有接口意味着JDK代理根本不可能。你可以插入目标bean并通过设置interceptorNames属性来指定拦截器列表。注意,即使将ProxyFactoryBean的proxyTargetClass属性设置为false,也会创建一个基于cglib的代理。,如果目标类实现了一个(或多个)接口,则创建的代理类型取决于ProxyFactoryBean的配置。,如果ProxyFactoryBean的proxyTargetClass属性被设置为true,则会创建一个基于cglib的代理。这是有道理的,也符合最小意外原则。即使ProxyFactoryBean的proxyInterfaces属性被设置为一个或多个完全限定的接口名,proxyTargetClass属性被设置为true这一事实也会导致基于cglib的代理生效。,如果将ProxyFactoryBean的proxyInterfaces属性设置为一个或多个完全限定的接口名,则创建一个基于jdk的代理。创建的代理实现了在proxyInterfaces属性中指定的所有接口。如果目标类碰巧实现了比proxyInterfaces属性中指定的更多的接口,那也没什么问题,但返回的代理不会实现这些额外的接口。,如果ProxyFactoryBean的proxyInterfaces属性没有被设置,但是目标类确实实现了一个(或多个)接口,那么ProxyFactoryBean会自动检测到目标类实际上至少实现了一个接口,并且创建了一个基于jdk的代理。实际被代理的接口是目标类实现的所有接口。实际上,这相当于为目标类的proxyInterfaces属性提供一个列表,其中包含目标类实现的所有接口。然而,这样做工作量大大减少,也不容易出现排版错误。,考虑一个使用ProxyFactoryBean的简单例子。这个例子涉及:,注意,interceptorNames属性接受一个字符串列表,其中包含当前工厂中拦截器或顾问的bean名称。你可以使用顾问,拦截器,返回之前,之后,并抛出建议对象。,前面给出的person bean定义可以代替person实现,如下所示:,同一个IoC上下文中的其他bean可以表达对它的强类型依赖,就像普通Java对象一样。如下面的例子所示:,这个例子中的PersonUser类公开了一个Person类型的属性。就它所关心的而言,AOP代理可以透明地代替“真实的”人实现。但是,它的类将是一个动态代理类。,如果需要代理一个类,而不是一个或多个接口,该怎么办?,想象一下,在我们前面的例子中,没有Person接口。我们需要建议一个名为Person的类,它没有实现任何业务接口。在这种情况下,你可以配置Spring使用CGLIB代理,而不是动态代理。为此,将前面给出的ProxyFactoryBean的proxyTargetClass属性设置为true。虽然最好是针对接口而不是类进行编程,但在处理遗留代码时,能够建议不实现接口的类可能很有用。(一般来说,Spring不是规定性的。虽然它使应用良好的实践变得容易,但它避免了强制使用特定的方法。),如果你愿意,你可以在任何情况下强制使用CGLIB,即使你有接口。,CGLIB代理通过在运行时生成目标类的子类来工作。Spring将这个生成的子类配置为将方法调用委托给原始目标。子类用于实现装饰器模式,在建议中编织。,CGLIB代理一般应该对用户透明。但是,有一些问题需要考虑:,通过在拦截器名称后面附加一个星号,所有bean名称与星号之前的部分匹配的顾问都被添加到顾问链中。如果你需要添加一组标准的“全局”顾问,这可以派上用场。下面的例子定义了两个全局advisor:

文章版权声明

 1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/22128.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年3月5日 上午12:00
下一篇 2023年3月7日 下午10:34