2012-06-25 69 views
2

我有一个请求范围的JSF 1.2托管bean,我需要重构为会话范围的bean,因为它在@PostConstruct上执行一些昂贵的操作,并且多次调用这真的只需要做一次。改变范围,会议的副作用是,现在我不能做这样的faces-config.xml注入FacesContext了:注入FacesContext作为会话范围的托管bean的托管属性

<managed-property> 
<property-name>context</property-name> 
<value>#{facesContext}</value> 
</managed-property> 

在那里我有

setContext(FacesContext ctx) {} 
在我管理的bean

在我的一个行动方法中,我需要上下文才能访问ExternalContext/HttpServletResponse。我不想调用

FacesContext.getCurrentInstance(); 

我的操作方法里面,但不知叫setContext(FacesContext ctx)外部允许范围内注射的隔离,便于嘲笑测试。我试着把setContext()放在@PostConstruct之内,后来才知道FacesContext是一个请求,而我的ExternalContext被重置为null,一旦有新的请求被提交。

虽然托管bean本身是会话作用域,但每次遇到新请求时我怎样才能自动调用setContext(FacesContext ctx)

回答

1

保留您的请求作用域bean并在其中注入会话作用域bean,以便您可以将FacesContext传递给请求作用域bean的@PostConstruct中的它。在会话范围的bean中,执行延迟加载/执行。

E.g.

public class RequestBean { 

    private FacesContext context; // Managed property. 
    private SessionBean sessionBean; // Managed property. 

    @PostConstruct 
    public void init() { 
     sessionBean.init(context); 
    } 

    // ... 
} 

public class SessionBean { 

    private SomeObject initializedObject; 

    public void init(FacesContext context) { 
     if (initializedObject != null) { 
      return; 
     } 

     initializedObject = initializeObject(context); 
    } 

    // ... 
} 
+0

是的,我结束了创建两个独立的托管bean像你提出解决问题。我之前苦苦挣扎,因为我试图融入单个托管bean。 – phewataal

+0

不客气。在会话范围的bean中注入'FacesContext'的唯一方法是使用CDI,但只有在使用Java EE 6时才可用。在使用古老的JSF 1.2时,显然完全没有问题。 – BalusC

+0

你会怎么做CDI? –