我将 Spring boot 与 JSF 2.2 一起使用。我的问题是我可以从javax.annotation.ManagedBean
创建@ManagedBean
并且当我运行应用程序时.xhtml它在我的索引中工作,但是当我想使用javax.faces.bean.ManagedBean
时不显示值。这两者之间有什么区别?为什么我不能使用javax.faces.bean.ManagedBean
?(我没有web.xml文件,一切都在类中配置)
javax.annotation.*
注解旨在从经典的 JSF 注解转移到 CDI 方法。Spring 框架能够读取一些 CDI 注释,所以这可能是这个注释"有效"的原因。然而,CDI的趋势是总体上使用@Named
。
在 Spring Boot 应用程序中,扫描注释的是 Spring,而不是 JSF。所以,即使你可以认为该应用程序适用于@ManagedBean
,你也会看到@*Scoped
注释是无用的,因为所有创建的 bean 恰好是单例,这是 Spring 的默认范围。
最后,我所做的选择是使用vanilla Spring注释和范围。由于 Spring 缺少 JSF 视图范围,因此也缺少一个自定义范围来模拟它。
MyBean.java:
@Component
@Scope("view")
public class MyBean {
//Here it goes your logic
}
查看范围.java:
public class ViewScope implements Scope {
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
if (viewMap.containsKey(name)) {
return viewMap.get(name);
} else {
Object object = objectFactory.getObject();
viewMap.put(name, object);
return object;
}
}
@Override
public String getConversationId() {
return null;
}
@Override
public void registerDestructionCallback(String arg0, Runnable arg1) {
}
@Override
public Object remove(String name) {
return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
}
@Override
public Object resolveContextualObject(String arg0) {
return null;
}
}
使用CustomScopeConfigurer
注册视图范围:
@Bean
public static CustomScopeConfigurer viewScope() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.setScopes(
new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build());
return configurer;
}
最后,不要忘记在你的faces-config中添加Spring EL解析器.xml以使Spring bean可以通过EL表达式使用:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
另请参阅:
- 为什么有不同的 Bean 管理注释
- 背豆(@ManagedBean)还是CDI豆(@Named)?
- 使用 JSF 配置 Spring 引导