简体   繁体   English

会话范围的 bean 在错误的 ApplicationContext 中泄漏

[英]Session-scoped bean leaks in wrong ApplicationContext

I have an application, that has 2 ApplicationContexts A and B , where A is the parent context of B .我有一个应用程序,它有 2 个 ApplicationContexts AB ,其中AB的父上下文。 B overwrites some beans from A , but also uses some of its beans. B覆盖了A一些 bean,但也使用了它的一些 bean。 For the frontend, I use Wicket and I have two Wicket applications AppA and AppB that use the respective Spring ApplicationContext.对于前端,我使用 Wicket,我有两个 Wicket 应用程序AppAAppB ,它们使用各自的 Spring ApplicationContext。

The problem now arises with a Session-scoped bean sessionBean , for which I have 2 different implementations: A defines a factory method returning an instance of sessionBeanA , B has a factory method with same signature returning an instance of sessionBeanB .现在问题出现在会话范围的 bean sessionBean ,我有两种不同的实现: A定义了一个返回sessionBeanA实例的工厂方法, B有一个返回sessionBeanB实例的具有相同签名的工厂方法。 The user now opens AppB and in the backend, we get an instance of sessionBeanB , wherever we inject a sessionBean , as we would expect.用户现在打开AppB并且在后端,我们得到sessionBeanB一个实例,无论我们在哪里注入sessionBean ,正如我们所期望的那样。 However, if the user now leaves AppB and opens AppA (still with the same underlying session), we get an instance of sessionBeanB injected in A , because the SessionScope object still holds the previously created bean object.但是,如果用户现在离开AppB并打开AppA (仍然使用相同的底层会话),我们会在A注入sessionBeanB一个实例,因为SessionScope对象仍然持有之前创建的 bean 对象。

How can I prevent that a session-scoped bean leaks in a different ApplicationContext?如何防止会话范围的 bean 在不同的 ApplicationContext 中泄漏? ApplicationContext A should not have to bother with beans from B ... ApplicationContext A不必理会B bean ...

Any help is highly appreciated.任何帮助都受到高度赞赏。

It's possible to extend the SessionScope from Spring to also consider the ApplicationContext by using a CustomScopeConfigurer as follows:可以通过使用CustomScopeConfigurer从 Spring 扩展SessionScope以考虑 ApplicationContext ,如下所示:

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());
  }
}

where CustomSessionScope is:其中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;
  }
}

and you can use it in the Java Spring configuration class with:您可以在 Java Spring 配置类中使用它:

@Bean
public static CustomScopeConfigurer configureSessionScope() {
  return new SessionScopeConfigurer();
}

It's maybe helpfull to change the scope of the Beans.更改 Bean 的范围可能会有所帮助。 Reduce the scope to @conversation.将范围缩小到@conversation。

Here you'll find more infomations about the scopes an contextes:在这里,您将找到有关上下文范围的更多信息:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM