2014-07-03 45 views
0

我有一個主要提供JSON API的服務器。目前我們擁有@Controllers,可以直接將REST端點委託給@Service類中的方法。可以使用@Service對象作爲@Controllers嗎?

這造成了大量不必要的樣板代碼。如果我用@Controller和@RequestMapping註釋簡單地註釋我的@Service類(例如,擰緊事務調用?與服務之間的依賴關係存在問題?),我是否會遇到問題?

回答

1

MVC模式存在是有原因的,讓每個層都能完成他們的工作,並且他們之間的耦合度較低。每個刻板印象都有其存在的理由。

你在說什麼樣的樣板代碼? @Controller和@RequestMapping非常簡單。

+0

說我有,每一個人都進行公開的10種方法10服務類REST API。我不需要實現每個服務類和註釋方法作爲REST API導出,我需要創建一個額外的10個控制器類,每個方法有10個方法,每個方法只返回service.method(param1,param2)。我現在有兩個需要保持同步的代碼塊 - 任何一個變化都需要改變另一個(=高耦合)。如果service = controller,則控制器的依賴關係仍與服務的實現和非@ RequestMapping方法分離。 – user48956

+0

關鍵是您可以在不更改REST層的情況下更改服務層,您可以在服務層中處理一些默認情況。你提出的建議基本上是建立一個良好的體系結構(將外部應用程序的核心應用程序與外部應用程序分離開來),帶來不便。此外,當你需要改變你的服務層時,應該很難,因爲你正在改變應用程序的核心。 –

4

如果你在同一個bean上同時使用@Service@Controller,你很可能會爲一個類創建兩個bean,這通常不是你想要的。

發生這種情況是因爲@Controller通常是在子上下文(調度程序servlet)中加載的。

如果你所有的bean都加載到調度程序servlet上下文中,你會沒事的。

編輯:我在我的iPhone中回答了這個問題,所以我不能詳細說明。

我說好機會這將是一個問題,因爲它確實與您使用的註釋類型無關,而是組件掃描以及如何將組件掃描分配給應用程序上下文。

大多數人所做的是掃描具有@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共享,那麼你可以使用@RequestMapping註釋@Service,它應該工作得很好,而不是我推薦的。

+0

我怎麼知道春天是否創建了2個重複的bean?我什麼時候可以看到他們? – Youssef

+1

使用2個「@ Component」特化註釋類型本身並不會創建兩個bean。 –

+1

*「好機會」*? – kryger

0

@Controllers將入口和終點委託給一個請求/響應。

@Service將向那些@Controllers提供邏輯,這些邏輯必須由@Controllers未知。

在@Controllers中,您必須@Autowired您的@Services依賴項。而在你的@Services中,你的其他邏輯依賴如DAO等等......

一個典型的休息@Controller看起來是這樣的:

@Controller 
public class UserWSController { 

    @Autowired 
    private UserService userService; 

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

     return this.userService.getUserById(userId); 
    } 

} 
1

難道我可能碰到的問題,如果我只是註釋與@Controller@RequestMapping註解我@Service

如果使用@Service進行註釋,則不需要使用@Controller對類型進行註釋。只要確保類型具有@RequestMapping註釋。處理映射控制器的處理程序方法的RequestMappingHandlerMapping會在類型級別檢查@Controller@RequestMapping註釋。你也需要。

除此之外,這只是一個設計和關注點分離的問題。在技​​術性的春季水平,你不會有任何其他問題。

(請注意,您必須加載通過DispatcherServletWebApplicationContextRequestMappingHandlerMapping豆把它撿起來。)

相關問題