我正在尝试将单个 SFSB 注入 Glassfish 3.1.1 中的 ViewScoped JSF 支持 bean。
我的日志显示了这一点,即创建了两个 SFSB,尽管只有第二个被注入:
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@f48cde0
INFO: constructed a new sfsb: com.exmaple.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191
后来,当我离开并且 ViewScoped bean 超出范围时,我在 SFSB 上调用 remove(),因此我在日志中看到了这一点:
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
但是以@f48cde0 结尾的多余的第一个从未被注入,所以我没有处理它,它永远不会被删除。只是后来,当我关闭服务器时,我看到它被删除了。
这是我的代码:
支持bean:
package com.example.test.ui;
import java.io.Serializable;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;
import com.example.test.service.api.TestSFSB;
@ManagedBean(name = "testViewScopedSFSB")
@ViewScoped
public class TestViewScopedSFSB implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(TestViewScopedSFSB.class.getCanonicalName());
@EJB
private TestSFSB testSFSB;
@PostConstruct
public void postConstruct() {
LOGGER.info("constructed a new view scoped bean: " + this);
}
public int getNumClicks() {
return testSFSB.getNumClicks();
}
public void clicked(AjaxBehaviorEvent event) {
testSFSB.clicked();
}
@PreDestroy
public void preDestroy() {
LOGGER.info("destroying view scoped bean: " + this);
testSFSB.remove();
}
}
SFSB 接口:
package com.example.test.service.api;
public interface TestSFSB {
void clicked();
int getNumClicks();
void remove();
}
SFSB 实施:
package com.example.test.service.impl;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Local;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import com.example.test.service.api.TestSFSB;
@Stateful
@Local(TestSFSB.class)
public class TestSFSBImpl implements TestSFSB {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(TestSFSBImpl.class.getCanonicalName());
int numClicks = 0;
@PostConstruct
public void postConstruct() {
LOGGER.info("constructed a new sfsb: " + this);
}
@Override
public void clicked() {
numClicks++;
}
@Override
public int getNumClicks() {
return numClicks;
}
@Override
@Remove
public void remove() {
LOGGER.info("removing sfsb: " + this);
}
@PreDestroy
public void preDestroy() {
LOGGER.info("destroying sfsb: " + this);
}
}
最后,jsf 页面:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h:html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<h:form>
<h:commandLink action="/public/publicResource.jsf" value="Home" />
<h:panelGrid id="panel1">
<h:commandButton value="Click me">
<f:ajax event="click" listener="#{testViewScopedSFSB.clicked}"
render="panel1" />
</h:commandButton>
<h:outputText value="#{testViewScopedSFSB.numClicks}" />
</h:panelGrid>
</h:form>
</h:body>
</h:html>
这是一个如此简单的设置......它到底是什么?也许是 Glassfish 中的一个错误?
编辑: 为了消除对我所报告内容的真实性的任何“怀疑”,这是我加载页面 10 次时的日志。注意创建了 20 个 SFSB,每次 2 个,但当我离开时只清理了 1 个。
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
最后,当我卸载应用程序时,请注意 10 个多余的 SFSB 最终被销毁:
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0
相信我的话,基于我的声誉,即该行为适用于 100 次点击,导致 200 个 bean 以相同的模式出现。