Любой перехватчик, который не использует полей экземпляра или другого общего состояния, является потокобезопасным:
Например, посмотрите на все встроенные перехватчики , которыеанализировать параметры HTTP-запроса и куки-файлы, выполнять регистрацию, проверку доступа, обработку исключений: они не используют поля экземпляра для изменяемого состояния (*), а просто работают с ActionInvocation
экземпляром, который они получают в качестве параметров.
(*) некоторые имеют поля экземпляра для параметров конфигурации, которые устанавливаются при запуске Struts (в одном потоке), например ExceptionMappingInterceptor
, или потоковые поля экземпляра, такие как Logger
в LoggingInterceptor
.
Если вы планируете написать свой собственный Interceptor
, работайте только с параметром ActionInvocation
, который вы передаете, и с локальными переменными в вашем методе intercept()
.Избегайте соблазна сделать метод перехвата synchronized
или поместить вещи в блок synchronized{}
- это создаст узкое место при подходе Struts к единственному экземпляру Interceptors.
Чтобы ответить на вопросы из комментариев:
(1) Почему создание экземпляра действия для каждого потока не влияет на производительность?
В современных JVM стоимостьсоздание объекта ничтожно мало.Не должно быть заметного влияния на производительность, если вы сохраняете свои действия легкими, избегая дорогостоящей инициализации, например, не создавая соединения с базой данных внутри действия, а используя пул соединений.
(2)рекомендовать НИКОГДА не использовать стек перехватчиков по умолчанию и всегда использовать собственный стек перехватчиков (где удаляются все неиспользуемые перехватчики, которые используют переменные экземпляра), чтобы он был потокобезопасным?
Не думаю, чтолюбые перехватчики по умолчанию, которые поставляются и конфигурируются с помощью Struts 2, не являются поточно-ориентированными;даже если они используют поля экземпляра (потому что они либо используются только для конфигурации, либо являются поточно-ориентированными, как Logger
).
По моему личному опыту, вы должны когда-либо касаться / изменять стек перехватчиков, только если выесть веская причина (потокобезопасность встроенных перехватчиков не одна).Многие вещи ведут себя / ломаются неожиданным образом, если вы меняете стеки - запуск одного из встроенных стеков, таких как «default» или «paramPrepareParam», экономит много разочарований в долгосрочной перспективе.Добавление собственных пользовательских перехватчиков обычно менее разрушительно, чем удаление / перестановка перехватчиков из существующего стека.