Spring Framework тот же объект при обновлении страницы, как этого избежать - PullRequest
1 голос
/ 28 сентября 2019

Вероятно, это вопрос новичка, и он связан с тем, как java обслуживает веб-сайт.Я пришел из фона PHP, где для каждого запроса очищается предыдущее состояние.

Почему при определении бина, как показано ниже, при обновлении страницы возвращается тот же хеш объекта?

@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 накапливается (показывая те же элементыснова и снова).Вопрос в том, как этого избежать?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

То, что написал @syedAmmar, является правильным, но не полным.
Создание вашего breadCrumbs прототипа - это только часть решения.это означает, что он будет создаваться при каждом вызове, а не только один раз.
Однако этого недостаточно, поскольку ваш контроллер является одноэлементным, что означает, что он создается только один раз, и вызывает компонент "хлебные крошки" только один раз..Вот почему вы получаете разные экземпляры на отдельных контроллерах, но не на отдельных вызовах.

, чтобы решить эту проблему, вам нужен ваш одноэлементный контроллер, чтобы получать разные прототипы для каждого запроса.
Один из способов сделать этоиспользуя интерфейс 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
  }
}

Подробнее об этом можно прочитать в этом руководстве

0 голосов
/ 28 сентября 2019

Это потому, что весной по умолчанию область действия компонента - Singleton, поэтому контейнер создает отдельный экземпляр этого компонента, и все запросы на это имя компонента возвращают один и тот же объект, который кэшируется.Если вам нужен новый экземпляр для каждого запроса, вам нужно сделать область действия prototype

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...