Как синглтон боб может быть Autowired в разных местах весенней загрузки - PullRequest
0 голосов
/ 27 сентября 2018

В этот момент я запутался, и я знаю, что все бины приложений весенней загрузки одноэлементны, насколько я понимаю, если у нас есть класс с аннотацией @Service, что бин может быть @Autowired только в одном классе (поправьте меняесли я ошибаюсь) вот код, который работает нормально, но я пытаюсь понять, как это работает?как один бин может быть @Autowired в двух разных классах?

Как * боб SampleService может быть @Autowired в SampleController2 и SampleController3 одновременно?

И эторекомендуемый подход?и в этом случае два потока могут параллельно изменять данные внутри бина?

SampleController2

@RestController
@RequestMapping(value="samplemock")
public class SampleController2 {

@Autowired
private SampleService2 sampleservice2;

@RequestMapping(value="/mock1",method=RequestMethod.GET)
public void mockCall1() {
    sampleservice2.m1();
   }

}

SampleController3

@RestController
@RequestMapping(value="samplemock2")
public class SampleController3 {

@Autowired
private SampleService2 sampleservice2;

@RequestMapping(value="/mock1",method=RequestMethod.GET)
public void mockCall1() {
    sampleservice2.m1();

   }
 }

SampleService2

@Service
 public class SampleService2 {

public void m1() {
    System.out.println("bean is autowired");
    }
 }

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Вот упрощенное представление о том, что Spring делает при запуске:

// Create bean: sampleService2
SampleService2 sampleService2 = new SampleService2();

// Create bean: sampleController2
SampleController2 sampleController2 = new SampleController2();
sampleController2.sampleservice2 = sampleService2; // because @Autowired

// Create bean: sampleController3
SampleController3 sampleController3 = new SampleController3();
sampleController3.sampleservice2 = sampleService2; // because @Autowired

Как видите, синглтон-компонент sampleService2 автоматически подключается как к sampleController2, так и к sampleController3.

Бины добавляются в хранилище, так что вы можете искать их по имени или типу в любой более поздний момент времени.

0 голосов
/ 27 сентября 2018

Цель внедрения зависимости и инверсии управления проста:

  • Вы определяете свои инъекционные средства (например, услуги) один раз , и они создаются один раз (если не указано иное).
  • Эти инъецируемые затем используются везде, где это применимо , и вы не контролируете их жизненный цикл, объем или состояние.

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

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

Для конкретного примера: javax.sql.DataSource - это интерфейс, который реализуетсямногие решения на основе JDBC, такие как MySQL, Postgres, Oracle и другие.Если вы хотите иметь два разных bean-компонента, которые взаимодействуют с двумя разными базами данных, но вы хотите использовать их взаимозаменяемо, вы определяете bean-компонент типа DataSource для использования и настройки , который получает источника данных.создано.Опять же, это включает в себя такие вещи, как @Qualifier, чтобы гарантировать, что вы подключите наиболее конкретный компонент в наиболее подходящее время.

Кроме того, последний момент довольно важен для ответа на эту часть вашего вопроса:

... и в этом случае два потока могут параллельно изменять данные внутри бина?

Это очень неразумно создаватьинъекционный боб со своим собственным внутренним состоянием.То есть, если вы SampleService присоединяетесь к какому-либо кешированному состоянию с коллекцией внутри него, вы в основном нарушаете ожидания, поскольку не знаете, когда или как часто в эту коллекцию будут добавлены элементы.или удалены из него.

Лучшее соглашение - иметь компоненты, которые могут ссылаться на сервисы с состоянием, но не сохранять это состояние в самом компоненте (например, соединение с базой данных, но не во всей таблице базы данных).

0 голосов
/ 27 сентября 2018

По умолчанию, как вы упомянули, все компоненты Spring являются синглетонами, но ваше второе предположение неверно: один и тот же компонент может быть автоматически подключен во многих других компонентах.

Фактически, в этом и заключается смысл того, что они являются синглетонами.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...