2015-02-09 31 views
3

我嘗試了使用JSF 2的聯合Spring 3(MVC)。我在Spring和JSF中有一些經驗,但從未嘗試過加入它們。最後,我有2個文件在JSF請求期間,@ManagedBean @Component類中的自動服務爲null

@ManagedBean(name = "userBean") 
@Scope 
@Component 
public class someBean { 

    @Autowired 
    private TestService testService; 

    public void printString() { 
    System.out.println(testService.getString()); 
    } 
} 

@ManagedBean(name = "studentBean") 
@Scope 
@Component 
public class StudentBean { 

    @Autowired 
    private TestService testService; 

    public void printString() { 
    System.out.println(testService.getString()); 
    } 
} 

對於這些文件,我有春天,JSF和web.xml正確的配置。並在.xhtml頁面中爲'someBean'和'StudentBean'啓動printString()。第一種情況下我有NPE,第二種情況下控制檯中有'一些字符串'。 原因很簡單 - Spring上下文和JSF中的不同bean名稱。後

@Component => @Component("userBean") 
public class someBean { 

完成了所有的問題在我看到

private TestService testService; 

@Autowired 
public void setTestService(TestService testservice) { 
    this.testService = testService; 
} 

當JSF的bean創建TestService的設置不爲空調試,但JSF生命週期時

public void pringString() { 
    testService.blah(); 
} 

TestService的期間爲空一片空白。這是我無法理解的。有人深入瞭解Spring和JSF來詳細描述這種情況嗎?

回答

6

JSF和Spring都可以充當bean容器。 @ManagedBean註釋指示JSF託管bean工具創建該類的新實例,並以給定名稱對其進行管理。 @Component註釋指示Spring ApplicationContext創建該類的新實例,並在給定名稱下對其進行管理。也就是說,JSF和Spring都創建了這個類的一個實例,JSF可以通過EL訪問,但Spring獲得了它的依賴注入(因爲作爲Spring註解,@Autowired不被JSF託管bean設施理解) 。所以你有一個選擇:使用JSF託管bean設施來完成所有任務(我不推薦這麼做,因爲它非常有限),使用CDI做任何事情(這是一個選項,但不使用Spring),或者通過刪除@ManagedBean註釋,並通過在您的faces-config.xml中註冊SpringBeanFacesELResolver來通過EL訪問Spring bean來實現所有功能(通常我都會使用Spring)。 Spring參考手冊在section 19.3.1中對此進行了描述。

+0

除此之外,對於這個問題的解決方案是驗證管理的bean必須使用'import javax.annotation.ManagedBean'而不是'導入將bean從「faces managed bean」(CDI)轉換爲「Spring managed bean」(ApplicationContext)的javax.faces.bean.ManagedBean'(導入可以使用@ManagedBean表示法) – Kurapika 2017-11-22 15:20:01

0

我相信testService爲null的原因是因爲在構造託管bean時testService尚未實例化。所以你可以使用@PostConstruct來將Spring bean注入到一個託管bean中。

@ManagedBean(name = "userBean") 
@Scope 
@Component 
public class someBean { 

    @Autowired 
    private TestService testService; 

    public void printString() { 
     System.out.println(testService.getString()); 
    } 

    @PostConstruct 
    private void init() { 
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
     ServletContext servletContext = (ServletContext) externalContext.getContext(); 
    WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext). 
            getAutowireCapableBeanFactory(). 
            autowireBean(this); 
    } 
} 

@Service 
public class TestService { 
    ...... 
} 
0

我有同樣的問題,它@ManagedBean annotation.My的屬性名是由於後臺bean看起來像這樣

@Component 
@ManagedBean(name="mainBean") 
@SessionScoped 
public class MainManagedBean{...} 

正如你看到的,給予豆名稱( mainBean)與支持bean應具有的默認名稱(mainManagedBean)不同。

我已通過將屬性名稱設置爲「mainManagedBean」來解決此問題。我的豆變成這樣:

@Component 
@ManagedBean(name="mainManagedBean") 
@SessionScoped 
public class MainManagedBean{...} 

我希望這可以幫助你