我在JSF 2.2中使用Spring Boot。我的问题是,当我运行该应用程序时,我可以@ManagedBean从javax.annotation.ManagedBean它创建它并在index.xhtml中运行,但是当我要使用时javax.faces.bean.ManagedBean却不显示该值。两者之间有什么区别?为什么我不能使用 javax.faces.bean.ManagedBean?(我没有web.xml文件,所有文件都在类中配置)
@ManagedBean
javax.annotation.ManagedBean
javax.faces.bean.ManagedBean
该javax.annotation.*注解就是从经典的JSF注释的移动到CDI方法。Spring框架具有读取某些CDI注释的能力,因此这可能是此注释“起作用”的原因。但是,CDI的@Named总体趋势是使用。
javax.annotation.*
@Named
在Spring Boot应用程序中,它是Spring扫描注释的文件,而不是JSF。因此,即使您可能认为该应用程序可以使用@ManagedBean,您也会看到@*Scoped注释没有用,因为所有创建的bean恰好都是singleton,这是Spring的默认范围。
@*Scoped
最后,我做出的选择是使用香草Spring批注和范围。由于Spring缺少JSF视图范围,因此还需要一个自定义范围来模拟它。
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; } }
使用以下命令注册视图范围CustomScopeConfigurer:
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.xml中添加Spring EL解析器,以使Spring Bean可通过EL表达式使用:
<application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application>