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
上阅读更多相关信息
这可能是一个新手问题,与 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
上阅读更多相关信息