当两个bean具有相同的范围时,托管属性值不会更新

时间:2013-04-01 16:52:44

标签: jsf-2 el

使用@ManagedProperty时,我看到了这种奇怪的行为。我有2个豆子:

UserManager (SessionScoped)

@ManagedBean
@SessionScoped
public class UserManager extends BaseBean implements Serializable
{
   private static final long serialVersionUID = 1861000957282002416L;

   private User currentUser;

   public String login() 
   {
      // set value of currentUser after authentication
   }

   public User getCurrentUser() {
      return currentUser;
   }

   public boolean isLoggedIn() {
      return getCurrentUser() != null;
   }
}

CartBean ALSO SessionScoped)

...
import javax.faces.bean.ManagedProperty;
...

@ManagedBean
@SessionScoped
public class CartBean extends BaseBean implements Serializable
{
   @ManagedProperty(value = "#{userManager.loggedIn}")
   private boolean loggedIn;

   public void updateCart(Movie selectedMovie)
   {
      if (!loggedIn) {
         return;
      }

      System.out.println("UPDATE CART REQUEST");

      int id = selectedMovie.getMovieID();

      if (cart.containsKey(id)) {
         cart.remove(id);
      }
      else {
         cart.put(id, selectedMovie);
      }
   }

   public void setLoggedIn(boolean loggedIn) {
      this.loggedIn = loggedIn;
   }
}

成功登录后,loggedIn 的值仍为

但是,如果我将CartBean的范围更改为@ViewScopedloggedIn的值会更新,我会看到sysout。

根据我的理解以及阅读各篇文章之后,只有在相同更广泛范围内,才能注入托管bean或其属性。但是“相同范围”的情况似乎在我的代码中不起作用。我在这里缺少什么?

我正在使用:

  • Mojarra 2.1.16
  • Spring 3.2
  • Hibernate 4.1
  • Tomcat 7.0.37

2 个答案:

答案 0 :(得分:5)

@ManagedProperty注释只能提供静态注入,这意味着注释属性将被注入当且仅当实例化持有@ManagedBean时。

当您部署应用程序时,我相信您的CartBean在开始时通过诸如View cart按钮之类的东西被引用。因此,注入过早发生并且因为bean是@SessionScoped,您将带有最初的false值,直到时间结束:)。

而不是只注入boolean字段,而应该注入整个UserManager bean:

@ManagedBean
@SessionScoped
public class CartBean extends BaseBean implements Serializable {
   @ManagedProperty(value = "#{userManager}")
   private UserManager userManager;

   public void updateCart(Movie selectedMovie) {
       if (!userManager.isLoggedIn()) {
           return;
       }

       ...
   }
}

答案 1 :(得分:0)

解决方案是使用Omnifaces它每次价值变化时都会为我工作

@ManagedBean
@ViewScoped
public class CartBean extends BaseBean implements Serializable {

   private boolean loggedIn;

   public void updateCart(Movie selectedMovie) {
loggedIn=Faces.evaluateExpressionGet("#{userManager.loggedIN}");
       if (!userManager.isLoggedIn()) {
           return;
       }

       ...
   }
}