Сегодня утром я смотрел кодовую базу в своей компании, и для меня это не было чем-то очень очевидным. Я работал с корпоративными проектами Spring MVC, но, по моему опыту, мне никогда не приходилось использовать прототип Scope. Я раньше видел его использование в некоторых классах, но для меня это было чем-то необычным.
Кодовая база
@RestController
@Scope("prototype") // this is set due to BaseEntity.setEntityManager
@RequestMapping(path = "/baseurl")
public class SampleController {
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
BaseEntity.setEntityManager(entityManager);
}
@RequestMapping (path = "/some-path")
public void getThis() {}
}
Здесь комментарий, в котором говорится, что this is set due to BaseEntity.setEntityManager
, не очень понятно, зачем это было сделано. Почему мне это кажется странным?
Потому что для каждого входящего запроса будет новый объект этого контроллера в JVM. Причем это сделано для ВСЕХ классов @RestController
. Итак, логично, что когда-нибудь при большом количестве запросов система может выбросить OOM. Придерживается ли он даже лучших практик?
Provided Scope подразумевает, что разработчик хотел сохранить состояние. Но как это связано с @PersistenceContext
?
Я не мог найти никаких доказательств того, почему это делается. Так что любые указания на то, что может быть причиной, были бы действительно полезны.
Значит, вы имеете в виду, что для каждого запроса нам нужен новый экземпляр EntityManager? Потому что это небезопасно. Да, определение видимости прототипа кажется излишним, так как же нам справляться с такими ситуациями?
@ K.Nicholas Я думаю, что смотрел на этот ответ. stackoverflow.com/questions/24643863/… Вероятно, внедренный контейнер EntityManager - это то, чего я должен с нетерпением ждать, если я выберу Spring bean без сохранения состояния. Мысли?
В этом случае это то же самое, что и область действия запроса, которая является нормой. EntityManager не является потокобезопасным, поэтому вам нужно убедиться, что один и тот же экземпляр не передается в несколько потоков. Об этом позаботится Request scoped. В области видимости прототипа говорится, что никогда не следует создавать один и тот же экземпляр дважды, но это излишне для варианта использования.