当前位置: 首页 > 知识库问答 >
问题:

会话作用域bean在错误的ApplicationContext中泄漏

张玺
2023-03-14

我有一个应用程序,它有两个ApplicationContextsAB,其中AB的父上下文B覆盖A中的一些bean,但也使用它的一些bean。对于前端,我使用Wicket,我有两个Wicket应用程序AppAAppB,它们使用各自的Spring应用程序上下文。

现在问题出现在会话范围的beansessionBean,对于它我有两种不同的实现:a定义一个工厂方法,返回一个sessionBeanA的实例,B有一个工厂方法,该工厂方法具有相同的签名,返回一个sessionBeanB的实例。用户现在打开AppB,在后端,我们会得到一个sessionBeanB的实例,无论我们在哪里注入sessionBean,正如我们所期望的那样。但是,如果用户现在离开AppB并打开AppA(仍然使用相同的底层会话),我们会在A中得到一个sessionBeanB实例,因为SessionScope对象仍然保存着先前创建的bean对象。

如何防止会话范围的bean在不同的Application ationContext中泄漏?应用上下文A不应该为来自B的bean而烦恼...

非常感谢您的帮助。

共有2个答案

蔺翰音
2023-03-14

更改bean的范围可能会有所帮助。将范围缩小为@conversation。

在这里,您可以找到有关范围和上下文的更多信息:

https://docs.jboss.org/weld/reference/2.4.0.CR1/en-US/html/scopescontexts.html

蒙胤
2023-03-14

可以从Spring扩展<代码> SessionScope <代码>,也可以通过使用<代码> CuoTraceEngigurue/Cuff>来考虑应用程序上下文:

import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public final class SessionScopeConfigurer extends CustomScopeConfigurer implements ApplicationContextAware {
  private final CustomSessionScope scope;

  public SessionScopeConfigurer() {
    scope = new CustomSessionScope();
    // Overwrite the session scope added by Spring
    addScope("session", scope);
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) {
    scope.setApplicationContextId(applicationContext.getId());
  }
}

其中CustomSessionScope为:

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.web.context.request.SessionScope;

/**
 * Extends {@link SessionScope} by modifying all bean names, so that they are specific to their ApplicationContext.
 * This avoids session-scoped beans from context a leaking through context b.
 */
public class CustomSessionScope extends SessionScope {
  private String applicationContextId;

  public void setApplicationContextId(String applicationContextId) {
    this.applicationContextId = applicationContextId;
  }

  @Override
  public Object get(String name, ObjectFactory<?> objectFactory) {
    return super.get(modify(name), objectFactory);
  }

  @Override
  public Object remove(String name) {
    return super.remove(modify(name));
  }

  @Override
  public void registerDestructionCallback(String name, Runnable callback) {
    super.registerDestructionCallback(modify(name), callback);
  }

  private String modify(String name) {
    // Attach ApplicationContextId to the bean name
    return name + applicationContextId;
  }
}

您可以在JavaSpring配置类中使用它:

@Bean
public static CustomScopeConfigurer configureSessionScope() {
  return new SessionScopeConfigurer();
}
 类似资料:
  • 问题内容: 我将JSF 2用于视图,将Spring用于业务逻辑。我正在尝试使用注解(@Scope(“ session”))将会话范围设置为我的一个Spring bean,但是却遇到了这个异常: 我知道RequestContextListener。在我的web.xml中。我还添加了RequestContextFilter: 似乎没有任何作用。我究竟做错了什么?谢谢! 问题答案: 尝试使用aop:sc

  • 我有一个关于会话范围的CDIBeans的生命周期的问题 据我所知,会话范围的CDIBean在会话启动时由容器构造,在会话结束时由容器销毁。在销毁bean之前,将调用@PreDestroy方法,如下所述https://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html.它还说用这种方法释放资源 在JSF应用程序中,我构建时遇到内存泄漏,因为bean似乎没

  • MyCart.java 这个MyCart Bean是每个HTTP会话实例化的名为CDI的Bean。 抽象类 问题描述 仅用于理解会话范围的CDI。我有两个JSP文件,如下所示 SetCDIBeanValue.jsp其中,我将获得命名会话CDI Bean(MyCart)的实例将It String属性的值设置为String值FROM_FIRST_JSP 因为这个会话的作用域是有限的,所以我想应该只有一

  • 我有一个springbean和scope会话。这个bean持有对另一个不可序列化的单例bean的引用。如果我想序列化会话范围的bean,最好的方法是什么? 这里已经提出了同样的问题:Spring会话范围的bean(控制器)和对服务的引用,在序列化方面 公认的答案是: 这个问题在Spring 3.0中通过提供一个非序列化bean的代理来解决,该代理从当前应用程序上下文中获取实例 据我所知,链接视频中

  • 恐怕这个问题会有点模糊,但这是... 我们注意到我们的JEE7 web应用程序中存在一些非常奇怪的、偶然的行为。有时,用户页面会突然开始显示来自完全不同用户会话的数据!到目前为止,我还没有能够复制这种现象,也没有在日志中找到任何问题的迹象,但是似乎一个用户的页面开始显示存储在@SessionScoped CDIBean中的数据,该CDIBean应该属于另一个用户的会话。 这种行为对任何人都有影响吗

  • 有没有办法销毁特定类的所有创建的会话范围bean(并在需要时让spring重新创建)? 例如,两个用户访问应用程序,然后每个用户将有一个bean。我想毁掉这两颗豆子。 用例: 管理员正在更新菜单栏。菜单栏列表数据存储在会话范围的bean中。管理员的bean应该被销毁,菜单栏应该被更新。当然,其他人的菜单也应该更新,所以其他bean也应该被销毁。 注1:不同的用户可能会看到不同的菜单,因此bean是