如何在JSF支持bean之间共享实体?

如何在JSF支持bean之间共享实体?,jsf,jsf-2,managed-bean,viewparams,Jsf,Jsf 2,Managed Bean,Viewparams,我想模块化我的JSF2.1/JavaEE应用程序。我有一个由几个模块组成的页面。每个模块都应该使用一个单独的JSF支持bean。其中一些模块需要显示和更改来自/来自同一实体的某些数据 我已经尝试过一些方法,但到目前为止我并不满意。我问自己最好的方法是什么 所有模块都使用相同的实体,如果某些数据发生更改,它们(可能)需要通知其他支持bean 对我已经尝试过的一些方法的评论: 通过接口将实体传递给我的组件(XHTML)也不会传递给支持bean 通常不鼓励使用“viewParam”方法,通过从请求参

我想模块化我的JSF2.1/JavaEE应用程序。我有一个由几个模块组成的页面。每个模块都应该使用一个单独的JSF支持bean。其中一些模块需要显示和更改来自/来自同一实体的某些数据

我已经尝试过一些方法,但到目前为止我并不满意。我问自己最好的方法是什么

所有模块都使用相同的实体,如果某些数据发生更改,它们(可能)需要通知其他支持bean

对我已经尝试过的一些方法的评论:

  • 通过接口将实体传递给我的组件(XHTML)也不会传递给支持bean
  • 通常不鼓励使用“viewParam”方法,通过从请求参数读取id在bean的postcontract方法中加载实体
  • 使用“viewParam”不如在bean创建之后使用实体(在我的postConstruct中)。我不确定bean的setter何时被调用
尽管“通常被劝阻”(由谁?),我在我的JSF-2.2支持bean中使用了以下技术之一(取决于我是否需要
personId
):


我想你需要的是CDI-。只需将您的页面切碎为多个较小的CDI bean,并根据需要将它们相互注入。

为什么不在会话中保存实体对象,并在所有bean中使用它呢?我不想在会话中膨胀。我正在寻找一种更适合JSF框架的解决方案。在会话中存储某些内容听起来像是一种解决方法。您肯定需要一个
@SessionScoped
/
@ApplicationScoped
托管bean。关于被通知的豆子,你需要更具体一些。为什么?RequestScope和ViewScope似乎足以满足我的需要。我希望实现所有bean都使用相同的实体实例,尽管一个bean可能会在一个操作中更改它的某些部分。它并不是指您的解决方案将@Param.@christorcuidennec注入属性,是的,但是
@Param
只是(一些非常坦率的)糖。原则是所有bean都同意一组参数名,这样它们就可以使用相同的实体。Nice。我喜欢将值注入bean。另一方面,bean知道参数的名称。@christorcurudenec是的,这是一个缺点。但是从名称到值的映射已经在某处发生了。如果你想保持干爽,你可以在
枚举中收集所有的参数名字符串。我所有的支持bean都已经是可以注入的CDI bean了。我对共享实体感兴趣。假设该实体是我从数据库中获得的客户。@ChristopherCudennec:如果您已经在使用CDI bean,只需将该客户注入bean X的1个,然后将该bean X注入其他bean以共享同一客户。我已经尝试过了。我希望这些bean是自治的,也就是说,它们不应该相互认识。@ChristopherCudennec:看来你正在尝试将你的应用程序分解成尽可能多的独立的小bean,然后将这些bean以不同的组合组合用于不同的目的/页面。尽管如此,注入旨在帮助bean以自我文档化的方式共享资源。如果您不想让他们相互了解,则必须使用中间人,例如
HttpSession
的属性来存储公共客户。这将是丑陋和混乱:)
@ViewScoped
public class BeanConverter {
    @Inject @Param(name = "personId")
    private ParamValue<Person> curPerson;
}

@ViewScoped
public class BeanConstruct {
    @PersistenceContext
    private EntityManager em;

    @Inject @Param
    private ParamValue<Long> personId;

    private Person curPerson;

    @PostConstruct
    public void init() {
        curPerson = em.find(Person.class, personId.getValue());
    }
}
public class BeanSending {
    @Inject
    private Event<PersonCreated> personCreatedEvent;

    public void constructPerson() {
        Person person = makePerson();
        personCreatedEvent.fire(new PersonCreated(person));
    }
}

public class BeanUpdater {
    public void updatePerson(@Observes PersonCreated evt) {
        doStuffWithPerson(evt.getPerson());
    }
}