Классы Spring MVC должны быть streamобезопасными

Если вы используете Spring MVC, должны ли ваши classы компонентов ( @Controller , @Service , @Repository ) быть streamобезопасными?

То есть, если у меня есть метод @RequestMapping в моем @Controller , может ли этот метод вызываться одновременно для одного и того же объекта controllerа более чем одним streamом?

( Раньше его спрашивали , но не отвечали как таковые).

    Данный

     @Controller public class MyController { @RequestMapping(value = "/index") public String respond() { return "index"; } } 

    Spring создаст экземпляр MyController . Это связано с тем, что Spring анализирует вашу конфигурацию, , видит @Controller (как @Component ) и создает экземпляр аннотированного classа. Поскольку он также видит @RequestMapping , он генерирует HandlerMapping для него, см. Здесь документы .

    Любые HTTP-запросы, которые получает DispatcherServlet будут отправлены в этот экземпляр controllerа через зарегистрированный ранее HandlerMapping , вызвав respond() через java-reflection в этом экземпляре.

    Если у вас есть поля полей, например

     @Controller public class MyController { private int count = 0; @RequestMapping(value = "/index") public String respond() { count++; return "index"; } } 

    count будет опасным, потому что он может быть изменен многими streamами, и изменения в нем могут быть потеряны.

    Вам нужно понять, как работают контейнеры Servlet. Контейнер создает экземпляр вашего экземпляра Spring MVC DispatcherServlet . Контейнер также управляет пулом streamов, который он использует для ответа на соединения, т. Е. HTTP-запросы. Когда такой запрос поступает, контейнер выбирает stream из пула и в рамках этого streamа выполняет метод service() в DispatcherServlet который отправляет на правильный экземпляр @Controller который зарегистрирован для вас Spring (из вашей конфигурации).

    Поэтому YES, Spring MVC classы должны быть streamобезопасными. Вы можете сделать это, играя с различными областями для полей экземпляра classа или вместо этого вместо этого вместо них должны быть локальные переменные. В противном случае вам потребуется добавить соответствующую синхронизацию вокруг критических разделов вашего кода.

    По умолчанию controllerы являются одноточечными и, следовательно, должны быть streamобезопасными. Тем не менее, вы можете настроить controllerы для запроса или сеанса, например:

     @Controller @Scope("session") public class MyController { ... } 

    Контроллеры с областью сеанса могут быть полезны для управления состоянием сеанса. Хорошее описание различных шаблонов можно найти в разделе «Использование сеансов в Spring-MVC (включая« scoped-proxies ») и в разделе« Как получить объект сеанса весной MVC » . Некоторые из представленных шаблонов требуют области запроса .

    Область запроса также полезна, если у вас есть данные, которые вы не можете позволить вычислить более чем на один запрос.

    Да, конечно.

    Лучше всего, если они являются апатридами, что делает их streamобезопасными по умолчанию. Если нет общего, изменяемого состояния, нет проблем.

    В основном ответ должен быть «да» и «нет». За исключением очень серьезной причины. Не потому, что Spring синхронизирует работу для вас – она ​​этого не делает (по умолчанию controller является компонентом Singleton). Грубая безопасность streamа должна поддерживаться по вызову метода, но обычно механизм Servlets стирает необходимость синхронизации чего-либо, потому что запрос выполняется внутри streamа. Таким образом, во время вызова любого аннотированного метода @RequestMapping весь стек вызовов выполняется в одном streamе. В корне он отправляется из методов service-do (Get, Post ..) сервлета, а затем отображается карта обработчиков, которая создается Spring (см. http://www.studytrails.com/frameworks/spring/spring-mvc -handler-mappings / http://technicalstack.com/dispatcher-servlethandlermapping-controller/, например). Spring вызывает метод обработки с карты обработчиков, после того как URL-адрес разрешен. Никаких других трюков. Так что подумайте, вы работаете внутри doPost (…), например, метода DispatchServlet. Является ли stream сервлета безопасным? Нет грубого. Можете ли вы сделать это streamобезопасным – да, используйте блокировки, синхронизированы, что еще и сделайте ваш Servlet узким местом! Точно так же и о controllerе. DoGet / Post / какой еще метод Servlet имеет в основном функциональную модель, все данные находятся в объекте HttpServletRequest. То же самое следует использовать в classах данных, используемых объектами Controller, и вместо стека вместо стека. Вы можете синхронизировать доступ к ним, но, заплатив цену за узкое место. Из грубого вы можете использовать атомику, так как это так необходимо? Если вам нужно сохранить какое-либо состояние во время сеанса, вы можете использовать @Scope («session») после @Controller или (для singleton controller) метод обработчика с сигнатурой (…, HttpSession), у обоих из них есть про и минусы. Но обратите внимание, что вы создали дополнительные затраты на CPU и GC. Во всяком случае, вы отвечаете за безопасность streamов Controller, когда хотите использовать поля и выйти из концепции без гражданства. Обычно кеш (redis, например) предпочтительнее для состояния клиента. По крайней мере, вы можете восстановить состояние, когда произошел сбой. Контроллеры состояния из сеанса не имеют оснований.

    Interesting Posts

    C #: HtmlAgilityPack извлекает внутренний текст

    Создание оператора конкатенации строк в R

    Почему я не могу сохранить изменения CSS в Firebug?

    Photoshop: пакетное изменение размера для веб-сайта

    В чем разница между дальними указателями и ближайшими указателями?

    Как я могу получить полный / абсолютный URL (с доменом) в Django?

    Может ли кто-нибудь объяснить, как BCrypt проверяет hash?

    MySQL сводная таблица

    Rsync-подобная автоматическая дельта-резервная копия съемного жесткого диска на окнах

    Нет маршрутов совпадений «/ users / sign_out» devise rails 3

    Не удалось обновить .NET framework 4

    Есть ли способ в Java преобразовать целое число в его порядковый номер?

    Почему git говорит, что «Pull невозможен, потому что у вас есть несвязанные файлы»?

    Использование значка шрифта Awesome для точек маркера с одним элементом элемента списка

    ASUS UX31A – отсутствует требуемый драйвер устройства привода CD / DVD

    Давайте будем гением компьютера.