管理会话 JSF 2.3 CDI
management sessions JSF 2.3 CDI
最近从 2.2
升级到 JSF 2.3
,我注意到 @ManagedBean
已被弃用,经过一些研究发现我应该使用 CDI-2.0
托管 beans 和@Named
注释。
我还将 @javax.faces.bean.SessionScoped
迁移到 @javax.enterprise.context.SessionScoped
。
但是我注意到我的 bean 是在服务器启动时创建的!
我使用用户 'X' 登录并更改了我的 bean 中的一个属性。之后我用另一个浏览器登录,我希望在我的属性中找到 null 但我在另一个浏览器中找到了用户 'X' 的最后更新。
我正在使用 myFaces 2.3、omnifaces 3.1,我还在 tomcat 中安装了 CDI。我参考了一些博客和 Whosebug 的一些回复,例如:
http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html
这是我的主要文件:
beans.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>
pom.xml:
.....
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>all-themes</artifactId>
<version>${primefaces.all.themes}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.omnifaces/omnifaces -->
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>net.bootsfaces</groupId>
<artifactId>bootsfaces</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.myfaces.core/myfaces-impl -->
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Oracle jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
.....
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>2.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
我是不是做错了什么?
我发现了问题并实施了解决方案,所以我想与您分享。
问题是 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;
..................
}
谢谢!
最近从 2.2
升级到 JSF 2.3
,我注意到 @ManagedBean
已被弃用,经过一些研究发现我应该使用 CDI-2.0
托管 beans 和@Named
注释。
我还将 @javax.faces.bean.SessionScoped
迁移到 @javax.enterprise.context.SessionScoped
。
但是我注意到我的 bean 是在服务器启动时创建的!
我使用用户 'X' 登录并更改了我的 bean 中的一个属性。之后我用另一个浏览器登录,我希望在我的属性中找到 null 但我在另一个浏览器中找到了用户 'X' 的最后更新。
我正在使用 myFaces 2.3、omnifaces 3.1,我还在 tomcat 中安装了 CDI。我参考了一些博客和 Whosebug 的一些回复,例如:
http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html
这是我的主要文件:
beans.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>
pom.xml:
.....
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>all-themes</artifactId>
<version>${primefaces.all.themes}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.omnifaces/omnifaces -->
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>net.bootsfaces</groupId>
<artifactId>bootsfaces</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.myfaces.core/myfaces-impl -->
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Oracle jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
.....
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>2.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
我是不是做错了什么?
我发现了问题并实施了解决方案,所以我想与您分享。 问题是 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;
..................
}
谢谢!