【问题标题】:Destroy all session scoped bean of a class销毁一个类的所有会话范围的bean
【发布时间】:2019-04-14 07:45:43
【问题描述】:

有什么方法可以销毁所有创建的特定类的会话范围 bean(并在需要时让 spring 重新创建)?

例如,有 2 个用户访问应用程序,那么每个用户将有 1 个 bean。我想销毁所有这两个豆子。

用例:

管理员正在更新菜单栏。菜单栏列表数据存储在会话范围的 bean 中。管理员的 bean 应该被销毁并且菜单栏应该被更新。当然其他人的菜单也应该更新,所以其他人的bean也应该被销毁。

注意 1:不同的用户可能会看到不同的菜单,因此 bean 是会话范围的,而不是单例的。

注意 2:我不想使用户的整个会话无效,而只是那个 bean

我找到this way 来销毁当前的作用域bean。但我无法从其他会话中销毁 bean。

((ScopedObject) myBean).removeFromScope();

非常感谢!!

【问题讨论】:

  • 正确的解决方法是避免在会话中存储这些与会话无关的数据。或者至少在访问时检查是否有更新,并在需要时刷新它。
  • 我想为菜单做一些缓存,不同的用户可能有不同的菜单(所以我想这是与会话相关的?如果我的理解有误,请告诉我)。所以我认为提高效率的方法是只在需要时刷新菜单数据(更新)
  • 它实际上与会话无关,因为它包含的数据在会话期间无效(如您的问题所示),并且其数据不受会话所属用户的控制到。再一次,我会让一切都变得无国籍。如果确实存在性能问题,则将整个配置缓存在一个单例 bean 中,并在需要时计算用户特定的菜单。如果仍然存在性能问题,请将菜单存储在会话中,但检查是否必须在每次显示时重新计算。
  • 我明白了。所以可能我应该遵循你的方法而不是搞乱用户会话!谢谢你的建议!
  • 您不能从其他用户会话中触摸会话。如果这是可能的,那将是一些安全漏洞。正如@JBNizet 指出的那样,数据与会话无关,因此只需将其放入缓存中并在更新后清除。

标签: java spring spring-boot javabeans session-scope


【解决方案1】:

销毁 bean 并重新创建它们似乎有点矫枉过正,也有点混乱。
对于这样的方法,我更喜欢事件,Spring 提供了一个 Spring Event API(spring-context 依赖项)。
您可以在 bean 类中注入一个 ApplicationEventPublisher 实例,该实例会引发其他一些 bean 的状态更改,这些 bean 可以注册一个偶数侦听器(@EventListener(condition = "...")) 以读取此更改事件。

例如发布者:

@Component
public class PublisherBean{

    private final ApplicationEventPublisher publisher;

    @Autowired
    public PublisherBean(ApplicationEventPublisher publisher) { ... }

    public void createOrder(Order order) {
        // ....
        this.publisher.publishEvent(new OrderCreatedEvent(order)); 
    }    
}

订阅者/听众:

@Component
public class ListenerBean{

  @EventListener(condition = "#creationEvent.awesome")
  public void handleOrderCreatedEvent(CreationEvent<Order> creationEvent) {
    ... 
  }

}

您可以看到更多信息here

【讨论】:

  • 您确定这适用于会话范围的 bean 吗?这些仅在为会话处理请求时才真正存在。
  • 老实说,从来没有使用会话范围的 bean 进行测试,因为通常我会在会话中消除它们并消除数据。如果 OP 没有以这种方式进行测试,我可以在示例项目中试一试。
  • 试过了,似乎它没有通过会话范围的bean(?)我不确定我是否写对了applicationEventPublisher.publishEvent(new CmsMenuUpdatedEvent(this));@EventListener() public void handleMenuUpdate(CmsMenuUpdatedEvent event) {},但感谢您告诉我这个惊人的事件监听器功能! !
  • 还有一个问题,你会选择什么时候发布事件并在监听器中处理,或者你什么时候选择直接从监听器调用方法?更新:实际上我可以进行另一项研究:) 无论如何谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2015-03-21
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
相关资源
最近更新 更多