我理解托管bean的工作方式类似于控制器,因为您唯一的任务是将视图层与模型“链接”。
要将bean用作托管bean,我必须声明@managedbean
注释,这样我就可以直接与bean进行JSF通信。
如果我想在这个managedBean中注入一些组件(来自Spring),我有两种可能的方法:
>
选择ManagedBean中的属性(如“basicdao dao”)并在该属性上方声明@managedproperty(#{“basicdao”})
。为此,我在ManagedBean中注入了Spring中的bean“basicdao”
。
我的理解正确吗?
首先,您应该选择一个框架来管理您的bean。您应该选择JSF或Spring(或CDI)来管理bean。虽然下面的工作,但它从根本上是错误的:
@ManagedBean // JSF-managed.
@Controller // Spring-managed.
public class BadBean {}
您最终得到了同一个托管bean类的两个完全独立的实例,一个由JSF管理,另一个由Spring管理。当您将其引用为#{someBean}
时,EL中实际上会使用哪一个并不直接清楚。如果在faces-config.xml
中注册了SpringBeanFaceselResolver
,那么它将是Spring管理的,而不是JSF管理的。如果您没有,那么它将是JSF管理的。
此外,当您声明特定于JSF托管bean的作用域时,例如@requestscoped
、@viewscoped
、@sessionscoped
或@applicationscoped
fromjavax.faces.*
包,它只能被@managedbean
识别和使用。@controller
无法理解它,因为它需要自己的@scope
注释。缺省时,这默认为singleton(应用程序范围)。
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
@Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean {}
当您通过#{someBean}
引用上述bean时,它将返回Spring管理的应用程序作用域bean,而不是JSF管理的视图作用域bean。
特定于JSF的@managedproperty
仅在JSF管理的bean中工作,即当您使用@managedbean
时。Spring特定的@autowired
仅在Spring管理的bean中工作,即当您使用@controller
时。以下方法是较少或较多等价的,不能混合:
@ManagedBean // JSF-managed.
@RequestScoped // JSF-managed scope.
public class GoodBean {
@ManagedProperty("#{springBeanName}")
private SpringBeanClass springBeanName; // Setter required.
}
@Component // Spring-managed.
@Scope("request") // Spring-managed scope.
public class GoodBean {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
}
请注意,当您按照javadoc在faces-config.xml
中注册了SpringBeanFaceselResolver
时,
<application>
...
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
因此,您可以通过#{springBeanName}
在EL中引用Spring托管bean,然后也可以在@managedproperty
中引用它们,因为它基本上设置了给定EL表达式的计算结果。另一方面,不支持通过@autowired
注入JSF托管bean。但是,当您从SpringBeanAutowiringSupport
扩展bean时,可以在JSF托管bean中使用@autowired
。这将在构造函数调用期间在Spring autowirable上下文中自动注册JSF托管bean实例,这意味着@autowired
中的所有内容都将在@postconstruct
和更高的版本中可用。
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport implements Serializable {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
@PostConstruct
private void init() {
// springBeanName is now available.
}
}
或者当您的体系结构不允许从不同的基类扩展bean时,您可以始终在Spring autowirable上下文中手动注册JSF托管bean实例,如下所示。另请参见如何很好地集成JSF2和Spring3(或Spring4)。
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
@PostConstruct
private void init() {
FacesContextUtils
.getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
.getAutowireCapableBeanFactory().autowireBean(this);
// springBeanName is now available.
}
}
Spring的@scope
对JSF作用域的支持有限。JSF的@viewscoped
没有等效的。基本上,您要么自行开发自己的作用域,要么坚持在Spring autowirable上下文中手动注册JSF托管bean实例,如上所示。
另一方面,Spring WebFlow通过新的@flowscoped
注释在JSF2.2中被接管。因此,如果您碰巧已经使用了JSF2.2,那么如果您只想要流作用域,就不一定需要使用Spring WebFlow。
从Java EE6开始,CDI就作为Spring DI的标准替代品提供了。它对此分别有@named
和@inject
注释,还有自己的作用域集。我不知道它如何与Spring交互,因为我不使用Spring,但是@inject
在@managedbean
内部工作,而@managedbean
内部的@managedproperty
可以引用@named
bean。另一方面,@ManagedProperty
不能在@named
bean中工作。
CDI的目的是将所有不同的bean管理框架统一到一个规范/InteFace中。Spring本可以是一个完整的CDI实现,但他们选择只部分实现它(只支持JSR-330javax.inject.*
,但不支持JSR-299javax.enterprise.context.*
)。另见Spring会支持CDI吗?而这个教程。
JSF将转向CDI进行bean管理,并在未来的版本中反对@managedbean
和friends。
@Named // CDI-managed.
@ViewScoped // CDI-managed scope.
public class BetterBean implements Serializable {
@Inject
private SpringBeanClass springBeanName; // No setter required.
@PostConstruct
private void init() {
// springBeanName is now available.
}
}
我理解托管bean的工作方式类似于控制器,因为您唯一的任务是将视图层与模型“链接”。 要将bean用作托管bean,我必须声明注释,这样我就可以直接与bean进行JSF通信。 如果我想在这个managedBean中注入一些组件(来自Spring),我有两种可能的方法: > 选择ManagedBean中的属性(如“basicdao dao”)并在该属性上方声明。为此,我在ManagedBean中注入
问题内容: 我正在使用框架JSF 2.1,Spring 3.1.1.Release,Hibernate 3.2.1进行Java EE项目。现在我正处于整合这三个方面的阶段。构建成功,我使用了tomcat服务器7。但是我在首页上看到了这个异常。 hibernatehibernate.cfg.xml hibernate.reveng.xml AnneeDao.java AnneeHibernateDa
我在演示应用程序中使用了JSF2+Spring3.1+Hibernate4,我想使用注释来创建会话工厂,但是我的DAO类没有在Jsf托管Bea类中初始化,所以我得到了空指针异常。我的ApplicationContext.xml 现在,在Managedbean方法中,DAO对象为null,我得到的是null指针异常
主要内容:实例,运行测试结果以下代码显示了如何进行bean注入。 我们先定义一个消息bean,它有一个字符串属性来存储消息。 然后我们再定义另一个托管bean,并使用注解注入。 实例 打开 NetBean8.2,创建一个名为: InjectManagedBeans 的工程,并加入以下文件代码。 以下是文件:UserBean.java 中的代码 - 以下是是文件:index.xhtml 中的代码 - 以下是文件:Message
通常,如果我必须在Spring中注入服务,我会使用 和
我正在开发一个遗留的JSF应用程序,我们正在慢慢地将其移植到Spring MVC。我们正在使用Spring Security来控制登录信息。在用户登录之后,JSF页面全局地实例化一个在任何地方都使用的会话作用域bean。我想更改应用程序,这样我们就可以先进入用Spring MVC开发的页面。 我尝试的一种方法是将bean转换为spring bean,并将其注入JSF,但不幸的是,这需要对bean进