Spring 页面刷新时框架相同的对象,如何避免它

Spring framework same object on page refresh, how to avoid it

这可能是一个新手问题,与 java 如何为网站提供服务有关。我来自 PHP 背景,对于每个请求,先前的状态都会被清除。

为什么当我定义一个 bean 时,如下所示,在页面刷新时返回相同的对象散列?

@Bean
public BreadCrumbs breadCrumbs()
{
    List<AssemblerInterface> assemblers = new ArrayList<AssemblerInterface>();
    assemblers.add(new BlogPostAssembler());
    return new BreadCrumbs(new RenderStrategy(), assemblers);
}

在我的控制器中:

System.out.println(breadCrumbs.hashCode());

在每个页面请求中,返回相同的哈希码:

817233364
817233364
817233364
817233364
817233364
817233364
817233364
817233364
817233364
817233364
817233364

并且 Breadcrumbs 组件的状态会累积(一遍又一遍地显示相同的项目)。问题是如何避免呢?

那是因为在 spring 中 bean 的默认作用域是 Singleton,所以容器会创建该 bean 的单个实例,并且对该 bean 名称的所有请求都将 return 同一个对象,这被缓存。如果你想在每个请求上都有一个新实例,你需要使范围 prototype

@Bean
@Scope("prototype")
public BreadCrumbs breadCrumbs()
{
  List<AssemblerInterface> assemblers = new ArrayList<AssemblerInterface>();
  assemblers.add(new BlogPostAssembler());
  return new BreadCrumbs(new RenderStrategy(), assemblers);
}

希望对您有所帮助。

@syedAmmar 写的是正确的,但不完整。
使您的 breadCrumbs 成为原型只是解决方案的一部分。这意味着它会在每次调用时创建,而不仅仅是一次。
但是,这还不够,因为您的控制器是单例,这意味着它只创建一次,并且只调用面包屑 bean 一次。这就是为什么您在不同的控制器上获得不同的实例,而不是在单独的调用上。

要解决这个问题,您需要单例控制器针对每个请求获得不同的原型。
一种方法是使用 Spring 的 ObjectFactory 接口:

@Controller
public class SomeController {

  private ObjectFactory<BreadCrumbs> breadCrumbsFactory;

  @Autowired
  public SomeController(ObjectFactory<BreadCrumbs> breadCrumbsFactory) {
    this.breadCrumbsFactory = breadCrumbsFactory;
  }

  public void something() {
    BreadCrumbs breadCrumbs = breadCrumbsFactory.getObject(); // this will give you a different instance on each call
  }
}

您可以在 this guide

上阅读更多相关信息