【问题标题】:Bean annotations like @ManagedProperty and @PostConstruct doesn't work when manually instantiating the bean from another bean当手动从另一个 bean 实例化 bean 时,像 @ManagedProperty 和 @PostConstruct 这样的 bean 注释不起作用
【发布时间】:2012-01-15 06:05:15
【问题描述】:

我从另一个请求 bean 实例化了一个请求 bean,

new LoginManager();

但是用@ManagedProperty 注释的属性没有从请求的引用中获取值,只有在通过上述方式实例化的情况下。它只包含null,导致代码后面出现 NPE。 @PostConstruct 也不会被调用。为什么会这样?我应该如何处理?

@ManagedBean(name = "loginManager")
@RequestScoped
public class LoginManager {

    private String userid;
    private String password;

    @ManagedProperty(value="#{currentSession}")
    private UserSessionManager userSession;

}

但是当使用new LoginManager(); 实例化此 bean 时,userSession 无法从会话范围的 bean 中读取:

但是我可以使用 FacesContext! 读取值!

【问题讨论】:

    标签: jsf jsf-2 annotations managed-bean


    【解决方案1】:

    您不应使用new 运算符手动实例化(管理)bean。您应该让 JSF 完成管理 bean 的工作,而是获取 JSF 管理的(JSF 实例化的)实例。

    @ManagedProperty 在你需要的 bean 中:

    @ManagedProperty("#{loginManager}")
    private LoginManager loginManager;
    

    或以编程方式调用 EL(在您的特定情况下这是非常接近的):

    LoginManager loginManager = context.getApplication().evaluateExpressionGet(context, "#{loginManager}", LoginManager.class);
    // ...
    

    如果您坚持自己实例化和管理 bean,您应该自己进行所有依赖注入,如果有的话,还应该自己调用 @PostConstruct,最后还要自己将 bean 放入所需的范围内。例如

    LoginManager loginManager = new LoginManager();
    loginManager.setUserSession(userSession);
    // Now use reflection to find and invoke @PostConstruct method.
    // Finally store in the map which conforms the bean's scope.
    externalContext.getRequestMap().put("loginManager", loginManager);
    

    这个样板正是 JSF 应该从你手中拿走的东西。好好利用吧。

    【讨论】:

    • 完美!太感谢了!在这两种方法中(使用@ManagedProperty 和evaluateExpressionGet),如果bean 已经存在,它们会被检索到吗?所以我什至不需要检查 bean 之前是否已经实例化 & 我可以直接使用,对吗?
    • 没错。 JSF 只会在它尚不存在于范围内时创建它,否则它只会返回现有实例。
    猜你喜欢
    • 2015-08-16
    • 2013-03-05
    • 2016-06-08
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    相关资源
    最近更新 更多