Ich versuche, ein einzelnes SFSB in einer ViewScoped JSF-Backing-Bean in Glassfish 3.1.1 zu injizieren.Überflüssiges SFSB, das in Glassfish erstellt wird und daher Speicher verliert
Mein Protokoll zeigt dies, das ist, dass zwei SFSBs erstellt werden, obwohl nur der zweite injiziert wird:
INFO: constructed a new sfsb: [email protected]
INFO: constructed a new sfsb: [email protected]e
INFO: constructed a new view scoped bean: [email protected]
Später, als ich weg navigieren und die ViewScoped Bohne geht out of scope, entferne ich aufrufen () auf der SFSB, und so sehe ich dies im Protokoll:
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]e
INFO: destroying sfsb: [email protected]e
Aber die überflüssige erstes in @ f48cde0 Endung wurde nie eingespritzt, so habe ich nicht einen Griff, um es, und es wird nie entfernt . Erst später, als ich den Server heruntergefahren habe, sehe ich, dass er entfernt wird.
ist hier mein Code:
Die Backing 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();
}
}
Die SFSB Schnittstelle:
package com.example.test.service.api;
public interface TestSFSB {
void clicked();
int getNumClicks();
void remove();
}
Die SFSB Umsetzung:
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);
}
}
Und schließlich die JSF-Seite:
<?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>
Das ist so eine einfache Einrichtung ... was zum Teufel könnte es sein? Ein Fehler in Glassfish vielleicht?
EDIT: Um keine „Zweifel“ an der Richtigkeit zu beschwichtigen, was ich berichte, ist hier das Protokoll, wenn ich die Seite 10 mal laden. Anmerkung 20 SFSBs erstellt, jedes Mal 2, aber nur 1 aufgeräumt, wenn ich weg navigiere.
INFO: constructed a new sfsb: [email protected]9
INFO: constructed a new sfsb: [email protected]9
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]9
INFO: destroying sfsb: [email protected]9
INFO: constructed a new sfsb: [email protected]9
INFO: constructed a new sfsb: [email protected]3
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]3
INFO: destroying sfsb: [email protected]3
INFO: constructed a new sfsb: [email protected]7
INFO: constructed a new sfsb: [email protected]7
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]7
INFO: destroying sfsb: [email protected]7
INFO: constructed a new sfsb: [email protected]e
INFO: constructed a new sfsb: [email protected]0
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]0
INFO: destroying sfsb: [email protected]0
INFO: constructed a new sfsb: [email protected]0
INFO: constructed a new sfsb: [email protected]
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]
INFO: destroying sfsb: [email protected]
INFO: constructed a new sfsb: [email protected]b
INFO: constructed a new sfsb: [email protected]a
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]a
INFO: destroying sfsb: [email protected]a
INFO: constructed a new sfsb: [email protected]8
INFO: constructed a new sfsb: [email protected]f
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]f
INFO: destroying sfsb: [email protected]f
INFO: constructed a new sfsb: [email protected]0
INFO: constructed a new sfsb: [email protected]b
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]b
INFO: destroying sfsb: [email protected]b
INFO: constructed a new sfsb: [email protected]5
INFO: constructed a new sfsb: [email protected]3
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]3
INFO: destroying sfsb: [email protected]3
INFO: constructed a new sfsb: [email protected]0
INFO: constructed a new sfsb: [email protected]c
INFO: constructed a new view scoped bean: [email protected]
INFO: destroying view scoped bean: [email protected]
INFO: removing sfsb: [email protected]c
INFO: destroying sfsb: [email protected]c
Und dann endlich, wenn ich die app entladen, beachten Sie die 10 überflüssig SFSBs schließlich zerstört werden; denn es basiert auf meinen Ruf
INFO: destroying sfsb: [email protected]9
INFO: destroying sfsb: [email protected]9
INFO: destroying sfsb: [email protected]7
INFO: destroying sfsb: [email protected]e
INFO: destroying sfsb: [email protected]0
INFO: destroying sfsb: [email protected]b
INFO: destroying sfsb: [email protected]8
INFO: destroying sfsb: [email protected]0
INFO: destroying sfsb: [email protected]5
INFO: destroying sfsb: [email protected]0
Nehmen Sie mein Wort, dass das Verhalten für 100 Treffer hält verursacht 200 Bohnen im gleichen Muster.
Ich denke nicht, dass das richtig ist. Ein beschränkter Cache (für Stateful Beans) unterscheidet sich von einem Pool (für Stateless Beans). Stateful Beans können nicht wiederverwendet werden. Das Verhalten, das ich sehe, ist 2 SFSB jedes Mal erstellt, wenn ich die Seite laden. Wenn ich die Seite 100 Mal lade, sehe ich 200 Beans erstellt. Die 100 "überflüssigen" Bohnen werden nie wieder verwendet; Es ist nicht so, als wären sie einem Pool hinzugefügt worden. Dies ist eindeutig kein wünschenswertes Verhalten. –
Es ist wahr, dass sie nicht in der gleichen Weise oder aus dem gleichen Grund wie Staatenlose vereint sind. Sie werden jedoch in diesem Fall konstruiert (die Objektinitialisierung ist in Java "teuer"), um für eine zweite + gleichzeitige Notwendigkeit verfügbar zu sein. Wenn es wirklich wahr ist, dass 200 nach 100 Anfragen erstellt wird, haben wir wirklich ein Problem (mit der Standardkonfiguration von Glassfish). Es tut mir leid, aber ich bezweifle, dass das der Fall ist. – esej
Re: "Zweifel" sehe meine Bearbeitung oben, einschließlich Protokolle –