管理会议JSF 2.3 CDI

时间:2018-06-06 11:06:56

标签: spring jsf cdi tomcat8 myfaces

最近从JSF 2.3升级到2.2后,我注意到@ManagedBean已被弃用,经过一些研究发现我应该使用CDI-2.0托管bean和{ {1}}注释。 我还将@Named迁移到@javax.faces.bean.SessionScoped

但是我注意到我的bean是在服务器的启动时创建的!

我使用用户'X'登录并更改了我的bean中的属性。之后我用另一个浏览器登录,我希望在我的属性中找到null,但我在其他浏览器中找到了用户'X'的最后一次更新。

我正在使用myFaces 2.3,omnifaces 3.1,我还在我的tomcat中安装了CDI。我引用了一些博客和一些响应stackoverflow,如:

http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html

Migrate JSF managed beans to CDI managed beans

以下是我的主要文件:

beans.xml中:

@javax.enterprise.context.SessionScoped

的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

我做错了吗?

1 个答案:

答案 0 :(得分:0)

我发现了问题,我实施了一个解决方案,所以我想和你分享。 问题是spring框架的组件扫描,这里是我的解决方案:

XML:

<context:component-scan base-package="com.example">  
    <context:exclude-filter type="aspectj" expression="com.example.beans.*" />  
</context:component-scan> 

注释:

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.example" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.example.beans.*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

第二个问题是关于spring的bean注入CDI bean,所以我在Spring和CDI之间建立了一个桥梁。

我必须创建一个这样的新注释:

@Qualifier
@Inherited
@Documented
@Retention(RUNTIME)
@Target({ FIELD, TYPE, METHOD, PARAMETER })
public @interface SpringBean {

    String value() default "";
}

和制片人:

@SessionScoped
public class CdiBeanFactoryPostProcessor implements Serializable {

    private static final long serialVersionUID = -44416514616012281L;

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{msg}", PropertyResourceBundle.class);
    }

    @Produces
    @SpringBean("example")
    public Example example(InjectionPoint injectionPoint) {
        return (Example) findBean(injectionPoint);
    }


    protected Object findBean(InjectionPoint injectionPoint) {
        Annotated annotated = injectionPoint.getAnnotated();
        SpringBean springBeanAnnotation = annotated.getAnnotation(SpringBean.class);
        ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

        String name = springBeanAnnotation.value();

        if(StringUtils.isNotBlank(name))
            return WebApplicationContextUtils.getRequiredWebApplicationContext(ctx).getBean(name);
        else 
            throw new NoSuchBeanDefinitionException(name, "not found in Context");

    }
}

然后我把它注入我的bean:

@Named
@SessionScoped
public class ExampleBean extends AbstractManagedBean  implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LogManager.getLogger(ExampleBean.class);

    @Inject
    @SpringBean("example")
    protected transient Example example;

    @Inject
    protected transient PropertyResourceBundle bundle;

..................

}

感谢!