Нитки весной - PullRequest
       24

Нитки весной

6 голосов
/ 23 апреля 2009

У меня есть веб-приложение, использующее Spring, Hibernate и Struts (оно работает на Tomcat)

Последовательность вызовов примерно такая ...

Действие Struts вызывает bean-компонент Spring Service, который, в свою очередь, вызывает bean-компонент Spring DAO. Реализация DAO является реализацией Hibernate.

Вопрос Будут ли все мои весенние бобы работать в одной и той же нити? Могу ли я сохранить что-то в ThreadLocal и получить это в другом бине?

Я совершенно уверен, что это не сработает в Session Bean без состояния. Контейнер EJB может (или будет) создавать новый поток для каждого вызова сессионного компонента

Будет ли пружинный контейнер делать то же самое? то есть запустить все бины в одном потоке?

Когда я попробовал тест JUnit - я получил тот же идентификатор через Thread.currentThread (). GetId () в тестовом примере и двух bean-компонентах, что наводит меня на мысль, что в действии был только один поток

Или поведение непредсказуемо? Или это изменится при работе на сервере Tomcat?

Разъяснение Я не хочу обмениваться данными между двумя потоками. Я хочу поместить данные в ThreadLocal и быть в состоянии извлечь их из всех компонентов в стеке вызовов. Это будет работать, только если все компоненты находятся в одном потоке

Ответы [ 4 ]

15 голосов
/ 23 апреля 2009

Весна не порождает темы. Tomcat делает. Spring просто создает и соединяет объекты для вас.

Каждый запрос от браузера обрабатывается в одном запросе. Это Tomcat, который обрабатывает запрос. Именно Tomcat создает поток для обработки запроса.

Предполагается, что вы только что создали синглтон-бин в Spring под названием «X». Затем один и тот же экземпляр X используется всеми запросами.

Весенние бобы не живут в потоке. Они просто распределяются по куче.

1 голос
/ 23 апреля 2009

Все мои весенние бобы в той же теме? Могу ли я хранить что-то в ThreadLocal и получить это в другой боб? AFAIK для компонентов, которые вы упомянули (служебный бин, DAO-бин - я думаю, это простые бобы Spring), Spring не создает новый поток. Я не понимаю ваш вариант использования (т. Е. Обмен данными между двумя потоками).

Для большинства веб-приложений новый поток создается для каждого нового запроса, и если вы хотите обмениваться данными между двумя запросами, вы обычно: - используйте параметры get / post для передачи данных - использовать сеанс для обмена данными

Чтобы ответить на ваш вопрос, я почти уверен, что пружинный контейнер не порождает потоки для большинства компонентов.

0 голосов
/ 24 апреля 2009

В дополнение ко всем остальным ответам я просто добавлю следующее:

Обычно единственной причиной для переключения потоков является некоторое требование параллельности. Поскольку это обычно не происходит бесплатно с точки зрения сложности, вы, как правило, будете четко проинформированы, когда это произойдет.

Переключение потоков в рамках однопоточной обработки запроса на самом деле чрезвычайно сложно. Обычно это происходит только в одном месте контейнера, и это обычно обрабатывается устройствами чтения сокетов tcp / ip, которые получают запрос от внешних клиентов. Эти потоки читателей обычно определяют, какой поток (пул) должен обработать запрос и направить запрос этому потоку. После этого запрос остается в этой теме.

Поэтому, как правило, единственное, что может / может произойти, - это создание дополнительных потоков для параллельности или асинхронной обработки (например, JMS).

0 голосов
/ 23 апреля 2009

Да, вы можете сделать это. Тот же поток будет использоваться для выполнения вашего действия, так что ThreadLocal будет работать. Как правило, один и тот же поток используется и для бина сеанса без сохранения состояния, если он работает в том же экземпляре сервера приложений. Хотя я бы не зависел от этого, поскольку он, вероятно, зависит от поставщика.

Мы используем эту технику для доступа к идентификатору вызывающего абонента в любом месте кода. Мы также используем сессионные компоненты и jms, но явно передаем информацию между контейнерами и устанавливаем ThreadLocal в каждой точке входа. Таким образом, не имеет значения, является ли bean-компонент (session или mdb) локальным или нет.

...