将 JSF 托管 bean 注释与 Spring 引导集成
Integrating JSF managed bean annotations with Spring Boot
我使用 Spring 引导和 JSF 2.2。我的问题是我可以从 javax.annotation.ManagedBean
创建 @ManagedBean
并且当我 运行 应用程序时它在我的 index.xhtml 中工作,但是当我想使用 javax.faces.bean.ManagedBean
不显示值。这两者有什么区别?为什么我不能使用 javax.faces.bean.ManagedBean
? (我没有web.xml文件,全部配置在类)
javax.annotation.*
注释意味着从经典的 JSF 注释到 CDI 方法的转变。 Spring 框架能够读取一些 CDI 注释,所以这可能是这个注释 "works" 的原因。然而,CDI 的趋势是使用 @Named
,总体而言。
在 Spring 引导应用程序中,Spring 扫描您的注释,而不是 JSF。因此,即使您认为应用程序可以使用 @ManagedBean
,您也会发现 @*Scoped
注释是无用的,因为所有创建的 bean 恰好都是单例,即 Spring' s 默认范围。
最后我做出的选择是使用香草 Spring 注释和范围。由于 Spring 缺少 JSF 视图范围,还有一个 custom scope 来模拟它。
MyBean.java:
@Component
@Scope("view")
public class MyBean {
//Here it goes your logic
}
ViewScope.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;
}
}
注册视图范围
@Bean
public static CustomScopeConfigurer viewScope() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.setScopes(
new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build());
return configurer;
}
最后,不要忘记在您的 faces 中添加 Spring EL 解析器-config.xml 以使 Spring beans 通过 EL 表达式可用:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
另请参阅:
- Why are there different bean management annotations
- Backing beans (@ManagedBean) or CDI Beans (@Named)?
- Configuring Spring Boot with JSF
我使用 Spring 引导和 JSF 2.2。我的问题是我可以从 javax.annotation.ManagedBean
创建 @ManagedBean
并且当我 运行 应用程序时它在我的 index.xhtml 中工作,但是当我想使用 javax.faces.bean.ManagedBean
不显示值。这两者有什么区别?为什么我不能使用 javax.faces.bean.ManagedBean
? (我没有web.xml文件,全部配置在类)
javax.annotation.*
注释意味着从经典的 JSF 注释到 CDI 方法的转变。 Spring 框架能够读取一些 CDI 注释,所以这可能是这个注释 "works" 的原因。然而,CDI 的趋势是使用 @Named
,总体而言。
在 Spring 引导应用程序中,Spring 扫描您的注释,而不是 JSF。因此,即使您认为应用程序可以使用 @ManagedBean
,您也会发现 @*Scoped
注释是无用的,因为所有创建的 bean 恰好都是单例,即 Spring' s 默认范围。
最后我做出的选择是使用香草 Spring 注释和范围。由于 Spring 缺少 JSF 视图范围,还有一个 custom scope 来模拟它。
MyBean.java:
@Component
@Scope("view")
public class MyBean {
//Here it goes your logic
}
ViewScope.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;
}
}
注册视图范围
@Bean
public static CustomScopeConfigurer viewScope() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.setScopes(
new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build());
return configurer;
}
最后,不要忘记在您的 faces 中添加 Spring EL 解析器-config.xml 以使 Spring beans 通过 EL 表达式可用:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
另请参阅:
- Why are there different bean management annotations
- Backing beans (@ManagedBean) or CDI Beans (@Named)?
- Configuring Spring Boot with JSF