Spring scope в приложении Dropwizard

#java #spring #spring-mvc

#java #spring #spring-mvc

Вопрос:

Если у меня будет следующая конфигурация в проекте Spring, и разные части приложения получат разные экземпляры ServiceA, у меня все еще будет проблема параллелизма, потому что все экземпляры ServiceA будут совместно использовать один экземпляр источника данных? Нужно ли мне просто знать, является ли BasicDataSource потокобезопасным? Если это так, то я в порядке, если это не так, то у меня будут проблемы с потоками?

 <bean id="serviceA" name="serviceA" class="com.company.ServiceA" scope="prototype">
    <constructor-arg name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" destroy-method="close" name="dataSource"
      class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="${dbConnectionUrl}"/>
    <property name="username" value="${user}"/>
    <property name="password" value="${password}"/>
    <property name="initialSize" value="${connectionSize}" />
    <property name="maxActive" value="${maxConnectionSize}" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true" />
</bean>
  

Ответ №1:

У вас не возникнет никаких проблем, если вы не используете какой-то очень странный источник данных. Все ваши компоненты в Spring должны быть без состояния, за исключением сеансовых компонентов. Готовые компоненты из Spring будут такими. Если вы сделаете это и в своем коде, у вас не возникнет никаких проблем. Все ваши одноэлементные компоненты могли бы быть по существу статичными, но это сделало бы их менее или не проверяемыми, так как вам было бы трудно издеваться над ними. Другая проблема, помимо параллелизма с наличием состояния в ваших компонентах, которые не являются сеансовыми компонентами, заключается в том, что если вы попытаетесь масштабировать свое приложение и развернуть несколько экземпляров одного и того же веб-приложения, оно, скорее всего, упадет. Обычно ваши компоненты не используют источник данных (хотя у вас тоже могут быть причины). Обычно вы работаете с фабрикой сеансов и просто получаете текущий сеанс с вашей фабрики сеансов, которая имеет ссылку на источник данных. Или с использованием аналогичного менеджера сущностей.

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

С фабрикой сеансов вам просто нужно прочитать об этом. Обычно вы используете что-то вроде hibernate для сопоставления классов с базой данных, и ваш сеанс похож на вашу ссылку на базу данных. Это обрабатывает все виды аспектов для работы с базой данных для вас. Подавляющее большинство приложений Spring похожи на это. Если вы загуглите Spring MVC hibernate, вы поймете, что я имею в виду.

Я полагаю, что есть большая дискуссия о том, может ли служба REST по-прежнему иметь сеансы, но я не могу это прокомментировать, хотя я знаю, что вы можете просто передать идентификатор сеанса в URL, но в любом случае, если у вас действительно нет сеансов и переменных, у вас не будет проблем с параллелизмом, если вы не ссылаетесь на очень странную библиотеку, просто потому, что никаких проблем не может быть, если нет общего состояния.

Комментарии:

1. «все компоненты должны быть без состояния». Как это защищает меня? область по умолчанию — singleton. Поэтому, когда Spring обрабатывает два запроса, потенциально не будут ли оба запроса выполняться через один и тот же компонент? Разве нельзя было бы переключить контекст в процессе обработки запроса?

2. » Обычно ваши компоненты не используют источник данных (хотя у вас тоже могут быть причины). Обычно вы работаете с фабрикой сеансов и просто получаете текущий сеанс с вашей фабрики сеансов, которая имеет ссылку на источник данных » — я не понял, что вы здесь говорили. Не могли бы вы немного уточнить?

3. на самом деле, я выполняю здесь службу REST, поэтому нет сеансов, о которых можно было бы говорить.

4. Но не путайте сеанс гибернации с сеансом HTML.