2010-01-26 71 views
8

我們目前正在爲一箇舊的webapp添加一些新功能,它只使用JSP,沒有任何前臺框架。我們最近添加了Spring,並且我們希望在我們修改過的JSP中自動調用我們的bean,而不是重寫所有使用SpringMVC,Struts2或Tapestry5的bean。在JSP中自動裝入Spring Bean的最簡單方法是什麼?

我們正在使用的類型的自動裝配,所以它導致獲得在JSP像這樣的代碼,而先前獲得的Web應用程序上下文(「WAP」):

MyDao myDao = (MyDao) wap.getBeansOfType(MyDao.class).values().toArray()[0]; 

我們想不使用這樣的代碼,而是直接在我們的JSP中直接注入我們的bean,就像我們在使用@Autowired註解的商業bean中一樣。

事實上,我們正在尋找最簡潔的方法來在我們的JSP中注入我們的bean。你用什麼 ?

+0

用SpringMVC左右的好處是,你沒有吞下整個藥片。你可以選擇你想要使用的彈簧部分。按斯蒂芬C指出並開始重構可能會更乾淨。 – SWD 2010-01-26 13:54:31

回答

9

你可以使用Spring的ContextExposingHttpServletRequest

HttpServletRequest的裝飾是 使得作爲 請求屬性,通過懶惰 檢查一次屬性得到 訪問在一個給定的 所有的Spring bean的WebApplicationContext訪問。

這需要控制器代碼封裝了原始HttpServletRequestContextExposingHttpServletRequest,再往前到JSP。它可以公開特定的命名bean或上下文中的每個bean。

當然,這只是將問題從JSP轉移到您的控制器代碼,但這可能是一個更易於管理的問題。

+1

您認爲如何將這個過濾器(而不是servlet)改變爲JSP的頂層,它從Spring上下文獲取所有bean,並將它們放在請求範圍中,並由預期的接口命名以獲得相似的getByType? – temsa 2010-01-26 14:22:43

+1

好主意,應該工作 – skaffman 2010-01-26 14:47:32

+0

(+1)很好的捕捉請求包裝。 仍然,'@ Autowired'將不可用那種方式? – Bozho 2010-01-26 14:58:30

7

您不能直接使用@Autowired,因爲您的jsps和servlet都是由servlet conainer實例化的。所以它們不是春天環境的一部分,因此它們的依賴不會被注入。

您可以:

  1. 移動所有的代碼,純servlet的,而不是在JSP中 - 只留下呈現在JSP中。在你的servlet
  2. 使用@Configurable(並添加javaagent,如鏈接的文檔中描述)

另一種方法,是手動使當前上下文的servlet的一部分。這是可能的兩個JSP和servlet:

public void init() { 
    WebApplicationContext ctx = WebApplicationContextUtils 
     .getRequiredWebApplicationContext(getServletContext()); 

    AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory(); 

    bf.autowireBean(this); 
} 

這將解決@Autowired註釋的依賴關係。

現在,我不確定是否需要使用servlet容器來使用只有一個實例的servlet類。如果不是,則最好將上面的代碼放在依賴項的getter方法中(getDao()),如果@Autowired屬性爲null(即容器使用另一個servlet類實例),請執行上述操作。


這一切都表示,真的考慮使用Web框架(任你列出的的)。在jsps中有邏輯是完全錯誤的,難以支持,難以閱讀等。

+1

我明確知道,但您可以在5天內不會重寫整個軟件(包括拆分前端和業務邏輯),同時添加新功能。事實上,我們應該避免在那裏使用DAO並寫入,然後只依賴於業務對象,但這只是一些已經寫好的代碼,我不能在這麼短的時間內重寫。 令人信服的管理人員將應用程序轉換爲Spring/Hibernate/Jpa而不是自制的單身人士和公司製造的ORM工具已經非常痛苦。他們只看到這是一個成本... – temsa 2010-01-26 15:21:04

4

我懷疑是否有一種乾淨的方式將依賴注入到JSP中。

我認爲乾淨的解決方案是開始重構代碼以使用SpringMVC或您引用的其中一種替代方法從JSP中獲取業務邏輯。

從一個或多個簡單控制器開始,該控制器簡單地將請求傳遞給JSP,並將注入的bean作爲屬性; @ skaffman的回答給出了一種方法來做到這一點,或者你可以更有選擇地做到這一點。然後逐步將代碼從JSP遷移到控制器中。

5

怎麼樣覆蓋jspInit()方法,並添加自動裝配支持:

<%@ page import="com.example.ExampleService"%> 
<%@ page import="org.springframework.beans.factory.annotation.Value"%> 
<%@ page import="org.springframework.beans.factory.annotation.Autowired"%> 
<%@ page import="org.springframework.web.context.support.SpringBeanAutowiringSupport"%> 
<%! 
    public void jspInit() 
    { 
     SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, 
     getServletContext()); 
    } 

    @Value("${example.property}") 
    private String someField; 

    @Autowired 
    private ExampleService exampleService; 
%> 

<% final Object data = exampleService.getSomething(someField); %> 
相關問題