在Spring框架中使用代理(动态代理)的含义是什么?

29

我不知道在Spring中使用代理的意义是什么,它是否高效?


你是什么意思说“什么是高效的?” - skaffman
5个回答

63

代理被AOP使用。简而言之:

通常你会有。

Caller --> Real object

例如,当您想要自动事务管理时,Spring会为您的真实对象放置一个代理。

Caller --> Proxy --> Real object

代理在何处开始事务。

这篇优秀的文章解释了Spring中代理的本质以及它们的效率(性能)。


7
博卓,这是一个非常好的解释。 - Jackie
下一个问题是 - 为什么Spring需要使用AOP呢?我只知道@Transaction注解。 - gstackoverflow
1
许多其他的事情。例如缓存、日志记录、审计跟踪,或者任何你自己可以开发的东西。 - Bozho

23

动态代理是JDK的一个特性。可以使用调用处理程序来实现接口。

动态代理类(以下简称代理类)是一个在创建该类时在运行时指定一系列接口,按照下面描述的方式实现行为的类。代理接口是由代理类实现的这样一个接口。代理实例是代理类的一个实例。每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler。

动态代理具有一些开销。对于大多数用例,开销不会很高。真正的问题是过度使用动态代理会使应用程序更难以理解和调试。例如,动态代理将在堆栈跟踪中显示多行。

动态代理通常用于实现装饰器。其中一个例子是Spring中的AOP。(我不想深入讨论AOP的细节,并且不会使用AOP术语来保持简单)。某些关注点在一个类中实现并在多个地方使用。动态代理(和调用处理程序)只是拦截方法调用的粘合代码(由Spring提供)。 (实际上,动态代理仅是此功能的实现细节。生成类是另一种实现它的可能性。)


为什么我们要实现这个?我想问一下方法论或类似的东西。 - Linh

2
我们可以通过修改源代码/字节码或使用子类或代理来为Java类添加功能,这些子类或代理嵌入了额外的功能并将调用委托给底层对象。

1
其他答案都很好,但以下是我用非常简单的方式来解释它。
1. 注解意味着“添加隐藏代码以实现额外的行为”。 2. 框架(或任何知道注解含义的东西)会添加字节码,例如Spring在运行时,AspectJ在编译时。 3. 它会添加代理和拦截器的代码。(包装器、装饰器、适配器类似且可能比“代理”更容易理解。) 4. 当程序运行时,拦截器将执行发送到代理,代理执行其操作,然后可能将执行发送到您编写的类并将其“包装”。

0
AOP 也可以使用 CGLIB 代理。这是用于代理类而不是接口的。

1
但是,只有在代理类(或方法)不是“final”时才会发生这种情况 - 这是因为CGLIB使用子类化(继承)来创建代理。 - kekko12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接