2013-03-06 66 views
3

已經變得非常舒適的依賴注入作爲一種風格,我發現自己寫的HTTP Servlet是這樣的:注入依賴成一個普通的老Tomcat的HTTP Servlet中

public class FooServlet extends HttpServlet { 

private Dependency dependency; 

public void setDependency(Dependency dependency) { 
    this.dependency = dependency; 
} 

@Override 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 

     ... 
     Result r = dependency.doSomething(...); 
     ... 
} 

這是美麗的容易單元測試,而且我很想保持模型 - 但現在我來部署它在Tomcat中,我意識到我不知道我可以從哪裏調用setDependency()。

浮現在腦海中一些模糊的可能性:

  • 獲取的servlet參數的init()。這些只是字符串,所以我不得不做一些反思來創建。這不是真的DI;只是配置了依賴關係創建。
  • 與JNDI之間的東西
  • 不知何故,從嵌入了Tomcat的Java程序中,讓Tomcat給我一個Servlet對象的引用,允許我調用它的setter。
  • 使用Spring。如果我使用Spring,我會尋找保持輕量級的方法。這個應用程序不夠複雜,不足以保證Spring MVC。

回答

0

感謝Aaron和Filipe,我發現了什麼似乎是Spring最輕量級的用法。

配置在調度servlet的WEB-INF/web.xml文件:

<servlet> 
      <servlet-name> 
        myDispatcher 
      </servlet-name> 
      <servlet-class> 
        org.springframework.web.servlet.DispatcherServlet 
      </servlet-class> 
      <init-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>/WEB-INF/spring/myDispatcher-context.xml</param-value> 
      </init-param> 
    </servlet> 

在WEB-INF /春/ myDispatcher-context.xml中,明確配置應用程序環境,使BeanNameUrlHandlerMapping時請求映射到你處理類,並且你的依賴被注入。

<bean id="/*" class="org.me.MyHandler"> 
     <property name="dependency" ref="dependency"/> 
    </bean> 
    <bean id="dependency" class="org.me.myDependency"/> 

編寫MyHandler作爲HttpRequestHandler的實現 - 它非常類似於Servlet。

這給你依賴注入。它避免了類路徑掃描,並且不會加載數十個類 - 但是如果您想在以後採用更高級的Spring MVC功能,那就有機會了。

2

我會使用Spring,因爲它提供了一個大的生態系統的功能和功能,可以用於您的項目,以加強它。但只有當你真的使用它們。加載如此龐大的框架只能在一個地方使用一個小功能是毫無意義的。

也就是說,你也應該小心,因爲doPost()方法將被不同的線程調用,而你的dependency對象是一個成員變量。這會使你的代碼變得不安全,因爲如果它是一個單獨的實例,同一個dependency實例可以被不同的線程同時使用。

+0

謝謝。有關線程安全性的問題與您應該考慮使用Spring bean網絡沒有什麼不同,對吧? – slim 2013-03-06 10:53:00

+0

你是對的。 – 2013-03-06 10:57:21

2

它實際上只是兩行代碼,使@Autowire工作在一個servlet:

ApplicationContext appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); 
appContext.getAutowireCapableBeanFactory().autowireBean(this); 

有一個缺點,雖然:Servlet是單身人士和他們不是由Spring創建的,所以你不能注入原型bean。所以,只要所有注入的bean都是單例,這就會工作。當你稍後添加一個原型bean時,代碼將會以奇怪的錯誤開始失敗。

因此,我通常會創建處理程序bean(請參閱HttpRequestHandler)並在doPost()中創建它們,而不是自動裝配servlet本身。