可以将@Service对象用作@Controllers吗?

时间:2014-07-03 18:27:49

标签: spring spring-mvc

我有一台主要提供JSON API的服务器。目前我们有@Controllers直接将REST端点委托给@Service类中的方法。

这会产生许多不必要的样板代码。如果我只是使用@Controller和@RequestMapping注释来注释我的@Service类(例如搞砸了事务调用?服务之间的依赖关系问题?),我可能会遇到问题。

4 个答案:

答案 0 :(得分:4)

如果在同一个bean上同时使用@Service@Controller,则很有可能为一个类创建两个bean,这通常不是您想要的。

这是因为@Controller通常在子上下文(调度程序servlet)中加载。

如果你的所有bean都在调度程序servlet上下文中加载,你就可以了。

编辑:我在iPhone上回答了这个问题,所以我无法详细说明。

我说好机会这将是一个问题,因为它与您使用的注释类型无关,而是与组件扫描以及如何将组件扫描分配给应用程序上下文无关。 / p>

大多数人所做的是扫描@Service要由根WebApplicationContext加载的组件,这些组件可以与调度程序servlet上下文相同,但通常不是。

让我举个例子:

通常,您会看到applicationContext.xml,其中包含以下内容:

<context:component-scan base-package="com.blah">
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

随后是一个带有以下内容的调度servlet上下文XML:

<context:component-scan base-package="com.blah" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

注意第一个如何排除@Controller,第二个明确包括。

如果您只有一个WebApplicationContext并且它与调度程序servlet共享,那么您可以使用@Service注释@RequestMapping,它应该可以正常工作,而不是我建议的那样。

答案 1 :(得分:1)

MVC模式存在是有充分理由的,让每个层完成它们的工作并且它们之间的耦合度很低。每个刻板印象都有理由存在。

您在谈论什么样的样板代码? @Controller和@RequestMapping很简单。

答案 2 :(得分:1)

  

如果我只是注释我的@Service,我是否会遇到问题?   包含@Controller@RequestMapping注释的类

如果使用@Controller进行注释,则不需要使用@Service注释该类型。只需确保类型具有@RequestMapping注释即可。处理控制器映射的RequestMappingHandlerMapping&#39; handler方法检查类型级别的@Controller@RequestMapping注释。你需要。

除此之外,它只是设计和关注点分离的问题。在技​​术性的Spring级别,你不会遇到任何其他问题。

(请注意,您必须通过DispatcherServlet WebApplicationContext加载bean,RequestMappingHandlerMapping才能将其取出。

答案 3 :(得分:0)

@Controllers将入口和终点委托给一个请求/响应。

@Service将为那些@Controllers提供逻辑,这些逻辑必须由@Controllers所知。

在@Controllers中,您必须@Autowired您的@Services依赖项。在你的@Services你的其他逻辑依赖,如DAO等......

一个典型的Rest @Controller看起来像这样:

@Controller
public class UserWSController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/{userId}")
    @ResponseBody
    public User getUserPublicInfo(@PathVariable int userId) {

        return this.userService.getUserById(userId);
    }

}