我有一个SFSB定义如下:
@Named("loginManager")
@Stateful
@SessionScoped
public class LoginManager {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
我有一个@Remove
注释方法:
@Remove
public void remove() {
log.info("loginManager removed");
}
但是当我在h:commandButton
中调用此方法时,会抛出异常:
16:19:32,640 FATAL [javax.enterprise.resource.webcontainer.jsf.context] (default task-64) #{loginManager.logout()}: org.jboss.weld.exceptions.UnsupportedOperationException: WELD-000037: Cannot call EJB remove method directly on non-dependent scoped bean public java.lang.String cn.fh.codeschool.action.LoginManager.logout(): javax.faces.FacesException: #{loginManager.logout()}: org.jboss.weld.exceptions.UnsupportedOperationException: WELD-000037: Cannot call EJB remove method directly on non-dependent scoped bean public java.lang.String cn.fh.codeschool.action.LoginManager.logout()
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89) [jsf-impl-2.2.6-jbossorg-3.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.6-jbossorg-3.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) [jsf-impl-2.2.6-jbossorg-3.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727) [undertow-core-1.0.5.Final.jar:1.0.5.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_21]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_21]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_21]
如何通过自己而不是容器来销毁SFSB?我发现当我申请SFSB时,会有很多bean被构造而不是一个。我真的很关心内存使用情况。
谢谢!
答案 0 :(得分:1)
来自文档:
retainIfException:如果为true,则如果从指定方法抛出异常,则不会删除有状态会话bean。
在生命周期结束时,客户端调用带注释的方法@Remove
,EJB容器调用带注释的方法@PreDestroy
(如果有)。然后bean的实例就可以进行垃圾收集了。
因此,在异常的情况下,容器不会移除bean。您可以调用此方法使其符合垃圾回收的条件。
@Remove(retainIfException=false)
public void remove() {
log.info("loginManager removed");
}
修改强>
如果应用程序调用{{1}}的会话bean实例上的remove()
,则会导致@Dependent
。
有状态会话bean可以定义一个删除方法,注释为@Remove, 应用程序用来指示实例应该是 销毁。但是,对于bean的上下文实例 - 实例 在CDI的控制下 - 这种方法只能被调用 应用程序,如果bean具有范围@Dependent。对于其他豆类 范围,应用程序必须让容器销毁bean。
答案 1 :(得分:0)
我已经明白了。
不应以这种方式使用SFSB。通常我需要将它注入托管bean,然后在该托管bean中调用SFSB的业务逻辑。
如果我们想通过调用@Remove
方法来销毁SFSB,我们应该删除该SFSB上的@Named
和@SessionScoped
注释。