在jsf中,bean应该如何与常规java类(也就是业务逻辑)进行通信

时间:2012-08-14 18:47:50

标签: jsf netbeans glassfish javabeans facelets

这是一个用Netbeans开发的关于glassfish的jsf项目。我尝试将我的bean连接到我的常规java类。

这是我的理解:
- 托管bean或其CDI等效项处理与UI相关的用户数据(例如,用户输入)
- 业务逻辑在常规java类中实现 - 2个托管bean或其CDI等效物可与@injection通信

我缺少的是:bean如何与常规java类进行通信? (我的业务逻辑在哪里?)
换句话说,我希望通过将bean作为构造函数的参数来运行我的java类!

我试过了:
- 在我的java类中包含@Inject注释,但这不起作用(bean未注入,保持为null) 像

public class myJavaProgram (){
@Inject
UserInputBean userInputBean;
//my business logic using the properties of userInputBean here...  //does not work, userInputBean is null!
}
  • 在我的java类的构造函数中将bean的属性作为参数传递。工作,但丑陋:为什么我不能简单地将整个bean作为参数传递给构造函数?但是当我这样做时,我的java类中的bean再次出现空指针异常。

    我错过了什么吗? THX!

2 个答案:

答案 0 :(得分:4)

现代企业应用程序通常在整个应用程序中使用依赖项注入模式,而不仅仅是表示层。所以你有一个数据访问层贡献bean,如EntityManager。它们被注入到构成业务服务层的业务服务中。反过来,业务服务被注入到您的JSF支持bean中。什么依赖注入容器最好是一个争论的问题,你也可以混合它们。

在Java EE 6标准中(至少我如何阅读它),EJB充当数据访问和业务服务层的依赖注入容器,CDI充当表示层的依赖注入容器(这就是为什么你可以注入CDI bean中的EJB)。其他人想要替换EJB并通过所有层使用CDI。然而其他人仍然从受到的伤害中获益,并使用Spring作为依赖注入容器。

要提供一些代码,您可以这样做:

@Named
@SessionScoped
public class UserBean {

    @Inject UserService userService;

    User user;

    public void save() {
        userService.create(user);
    }

}

@Stateless
public class UserService {
    public void create(User user) { ... }
}

答案 1 :(得分:2)

我认为当你说CGI时你实际上是指CDI ......

这是一个IoC(控制反转)框架,用于在JSF应用程序中实现DI(依赖注入)。这种框架的另一个例子是Spring,它正在慢慢开始采用更好的JSF支持。

如果您打算将托管bean中的业务逻辑分离到CDI注入的bean中,那么JSF托管bean的角色就是您的Presentation Logic的View Controller和存储库的角色。

@Inject注释只会注入已通过CDI配置的对象,这取决于您的项目设置可能实际上也可能不包含JSF Managed Beans。这一切都取决于您如何配置项目以及正在使用的EL Resolver实现。如果它是JSF实现的默认EL解析器(例如Mojarra),那么正在使用EL解析器的JSF实现,并且您的IoC将无法识别这些依赖关系。

您当然可以将托管bean的依赖注入到其他托管bean中,但您需要通过EL解析器执行此操作。

@ManagedProperty("#{userInputBean}")
UserInputBean userInputBean;

您引用的其他Java类依赖项应代表您的业务逻辑层,应由CDI配置并通过CDI处理。