@SessionScoped CDI bean 注入时是不同的实例
@SessionScoped CDI bean is a different Instance when injected
我的配置是一个 bean,我将它注入我的代码中任何需要的地方。但是,在注入时,我得到了一个新的 bean 实例,而不是会话中的实例。
我的豆子:
@Named
@SessionScoped
public class TestModel implements Serializable {
private static final long serialVersionUID = 4873651498076344849L;
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public void changeVersion() {
this.version = "Version 2";
System.out.println("New version : " + version + ", Object : " + this);
}
}
当注入不同的 类 时,所有出现的实例都是不同的。
用@ApplicationScoped注解bean时,是同一个实例。
我确实需要将 bean 设置为 @SessionScoped,因为每个用户都应该有自己的配置。
WebApp 在 TomEE 1.7.4
上 运行
更新:我创建了一个新项目来测试它,SessionScope 可以正常工作。我现在需要找出我当前项目的问题以便修复它。
方面:
- CDI 1.0
- 动态网络模块 3.0
- Java1.8
- JSF 2.2(来自 TomEE 的 MyFaces 实现)
- JPA 2.1
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Project</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>omega</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
人脸-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">
</beans>
有什么想法吗?
你做得对。也就是说,从 CDI 的角度来看,你没有犯错,你想要的是完全合法的,应该可以工作(假设你解决了多会话的问题,你做到了)。
我刚刚用我自己的一段代码尝试了这个,它按预期工作。你可以check it on GitHub。样本与您的大致相同。
但是,我是运行 Wildfly 10,因此是它附带的Weld 2.3(Weld是CDI的参考实现)。当您是 运行 TomEE 时,它包含 OpenWebBeans(另一个 CDI 实现)。
对我来说,您似乎错过了一些 TomEE/OWB 特定配置(不切实际的情况),或者更有可能的是,您发现了错误。无论如何,如果我是你,我会尝试在他们的论坛上提问或在他们的 tracking system 中创建一个问题,因为,恕我直言,你的 bean/servlet 设置没有任何问题。
看起来你的测试不起作用:
testModel object = model.TestModel@689a6064
New version : Version 2, Object : model.TestModel@61606aa6
所以你更新了一个与链接到会话的实例不同的实例(另一个请求不重用我会说的同一个会话)
我们在 JSF 和 CDI 中都有 @SessionScope
注释。请检查您在旧项目中使用的注释是来自 JSF 还是来自 CDI。
在 difference between the annotation from JSF & CDI
上查找更多信息
我的配置是一个 bean,我将它注入我的代码中任何需要的地方。但是,在注入时,我得到了一个新的 bean 实例,而不是会话中的实例。
我的豆子:
@Named
@SessionScoped
public class TestModel implements Serializable {
private static final long serialVersionUID = 4873651498076344849L;
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public void changeVersion() {
this.version = "Version 2";
System.out.println("New version : " + version + ", Object : " + this);
}
}
当注入不同的 类 时,所有出现的实例都是不同的。 用@ApplicationScoped注解bean时,是同一个实例。
我确实需要将 bean 设置为 @SessionScoped,因为每个用户都应该有自己的配置。
WebApp 在 TomEE 1.7.4
上 运行更新:我创建了一个新项目来测试它,SessionScope 可以正常工作。我现在需要找出我当前项目的问题以便修复它。
方面:
- CDI 1.0
- 动态网络模块 3.0
- Java1.8
- JSF 2.2(来自 TomEE 的 MyFaces 实现)
- JPA 2.1
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Project</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>omega</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
人脸-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">
</beans>
有什么想法吗?
你做得对。也就是说,从 CDI 的角度来看,你没有犯错,你想要的是完全合法的,应该可以工作(假设你解决了多会话的问题,你做到了)。
我刚刚用我自己的一段代码尝试了这个,它按预期工作。你可以check it on GitHub。样本与您的大致相同。
但是,我是运行 Wildfly 10,因此是它附带的Weld 2.3(Weld是CDI的参考实现)。当您是 运行 TomEE 时,它包含 OpenWebBeans(另一个 CDI 实现)。
对我来说,您似乎错过了一些 TomEE/OWB 特定配置(不切实际的情况),或者更有可能的是,您发现了错误。无论如何,如果我是你,我会尝试在他们的论坛上提问或在他们的 tracking system 中创建一个问题,因为,恕我直言,你的 bean/servlet 设置没有任何问题。
看起来你的测试不起作用:
testModel object = model.TestModel@689a6064
New version : Version 2, Object : model.TestModel@61606aa6
所以你更新了一个与链接到会话的实例不同的实例(另一个请求不重用我会说的同一个会话)
我们在 JSF 和 CDI 中都有 @SessionScope
注释。请检查您在旧项目中使用的注释是来自 JSF 还是来自 CDI。
在 difference between the annotation from JSF & CDI