1

I was looking at Spring MVC's documentation and I saw a mention about if your controller implemented an interface and was proxied you'd have to put the annotations on your interface or proxy by target class since otherwise the annotations wouldn't be picked up (the proxy wouldn't contain the annotations since it would be another class wrapping your bean via the exposed interface if it wasn't a subclass of the controller class).

However, in my experience controllers are supposed to be the simplest things out there - get the web-based inputs (formatting/creating the "model"), decide on the flow control to execute by delegating to business service layer interfaces/classes (controlling based on the state of the model), and then sending the model to the view layer to compose the resulting view.

Can anyone provide a really good use case of why you'd want to proxy a controller? Service layer methods, sure, but a controller?

4

1 回答 1

0

您代理控制器的原因是执行Proxy AOP

代理 AOP 过去仅适用于仅代理接口的动态代理。但是我认为 Spring 现在支持 CGLIB 代理。

就我个人而言,我通过使用 Spring 也支持的真实编译时 AspectJ 完全避免了基于代理的 AOP。

为什么要对控制器进行 AOP?为了避免样板代码,例如:安全性、输入清理、日志记录(所有这些我都在我的请求控制器上执行)。

编辑:昨晚我打算增加这个答案,因为我知道你会有后续行动。

是的,今天有请求,您可以使用 servlet 过滤器和拦截器执行大量 AOP,并且我确实在过滤器中拥有大部分横切代码,但与今天的 3.0 相比,当 Spring 首次引入其AnnotationMethodHandler(~2.5)时,情况并非如此AnnotationMethodHandler > 3.0(请注意通过设置器添加的过多策略组件)。

您可能想要使用 AOP 的一个真实的当前@PreAuthorize示例是在您的请求控制器中使用 Springs 安全注释(即),而不必在 XML 文件中放置一个拦截器(参见这个问题和我的答案)。或者您可能不需要服务层并且想要使用@Transaction.

我在控制器中使用 AOP 的另一个原因是它更具声明性,并且在我直接对方法调用进行单元测试时会起作用(当然我不使用代理,而是使用 AspectJ)。事实上,我使用类似于 Python 的装饰器的 AspectJ来声明性地包装带有样板代码的方法。过滤器不知道您注释了什么,因此您无法在此处执行此逻辑。

最后,有些人认为,对于小型 Web 应用程序或仅 REST 应用程序,额外的服务层被高估了,并且活动记录/DAO 加上控制器就足够了(参见 Spring Roo ......它最近才添加了一个服务层)。在这种情况下,如前所述,您通常需要@Transaction控制器中的支持。

否则,现代 Java(和/或 AspectJ)确实没有一个好的用例。恕我直言,我不再使用动态代理了。

于 2012-08-20T21:17:41.397 回答