我正在查看Spring MVC的文档,我看到提到你的控制器是否实现了一个接口并且代理了你必须通过目标类将注释放在你的接口或代理上,否则注释将不会被选中up(代理不包含注释,因为如果它不是控制器类的子类,它将是通过公开接口包装bean的另一个类)。
然而,根据我的经验,控制器应该是最简单的东西 - 获取基于Web的输入(格式化/创建“模型”),通过委托业务服务层接口决定要执行的流控制/类(基于模型的状态进行控制),然后将模型发送到视图层以组成结果视图。
任何人都可以提供一个非常好的用例,说明为什么要代理控制器?服务层方法,当然,但控制器?
答案 0 :(得分:0)
代理控制器的原因是Proxy AOP。
代理AOP过去只与dynamic proxies一起使用,它只会代理接口。但是我认为Spring现在支持CGLIB代理。
我个人通过使用Spring支持的实时编译时间来完全避免基于代理的AOP。
你为什么要AOP你的控制器?为了避免样板代码,例如:安全性,输入清理,日志记录(我在请求控制器上执行所有操作)。
编辑:我打算昨晚增加这个答案,因为我知道你会有一个后续行动。
是 TODAY 请求你可以使用servlet过滤器和拦截器做很多AOP我在过滤器中确实有大部分的交叉代码但是在Spring首次引入时并非如此其AnnotationMethodHandler (~2.5)与今天的3.0 AnnotationMethodHandler > 3.0相比较(通过制定者注意到过多的其他策略组成部分)。
一个真正的当前示例,说明您可能想要使用AOP的原因是在请求控制器中使用Springs Security Annotations(即@PreAuthorize
)而不必将拦截器放入XML文件(参见this question and my answer)。或者您可能不需要服务层,并且想要使用@Transaction
。
我在我的控制器中使用AOP的另一个原因是它更具说明性,并且在我单元测试直接调用方法时会起作用(授予我不使用代理而是使用AspectJ)。 In fact I use AspectJ similar to Python's Decorator声明性地用锅炉板代码包装方法。过滤器不知道您注释了什么,因此您无法在那里执行此逻辑。
最后,有些人认为对于小型Web应用程序或仅REST应用程序而言,额外的服务层会被高估,而活动记录/ DAO加控制器就足够了(参见Spring Roo ......它最近刚添加了一个服务层)。在前面提到的情况下,您经常需要控制器中的@Transaction
支持。
否则,现代Java(和/或AspectJ)确实没有一个好的用例。恕我直言,我不再使用动态代理了。