Как производить прототипы объектов из синглтона?(Нужна помощь в дизайне) - PullRequest
9 голосов
/ 26 мая 2011

Я относительно новичок в весне, и меня вырыли в яме.Я пытаюсь моделировать автомобили.Каждая модель имеет свой собственный объект построителя, и у меня есть BuilderFactory, который возвращает правильного построителя на основе выбора пользователя из веб-приложения.

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

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

Верхний уровень веб-приложения выглядит так:

Vehicle vehicle = vehicleBuilderFactory.getBuilder(platform).build();

Мой VehicleBuilderFactory выглядит следующим образом;

@Service
public class VehicleBuilderFactory {

@Autowired
Discovery3Builder discovery3Builder;
@Autowired
Discovery4Builder discovery4Builder;

    // Lots of @Autowired statements here. 

@Autowired
FreeLander2010Builder freeLander2010Builder;



public VehicleBuilder getBuilder(Platform platform) {

    switch (platform.getId()) {

    case 1: return discovery3Builder;
    case 2: return discovery4Builder;

            // Lots of case statements here

            case 44: return freeLander2010Builder;
    default: return null;
    }
}

}

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

@Service
public class DefenderBuilder implements VehicleBuilder {

@Autowired
Defender defender;

// Loads of Defender specific setters ommitted  
@Override
public Vehicle build() {
    return defender;
}

}

и, наконец, отдельный автомобиль

@Service
@Scope("prototype")
public class Defender extends Vehicle {

}

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

Ответы [ 3 ]

12 голосов
/ 26 мая 2011

Вы можете использовать Spring's ObjectFactory , чтобы он обслуживал прототипы с областью действия из одного объекта.Использование довольно простое:

@Component
class DefenderBuilder implement VechicleBuilder {

  @Autowired
  ObjectFactory<Defender> defenderFactory;

  Defender build() {
     return defenderFactory.getObject()
  }
}

@Component
@Scope("prototype")
class Defender {

}

Это возвращает нового Защитника при каждом вызове defenderFactory.getObject ()

0 голосов
/ 15 июля 2018

Две вещи: 1) Вы можете использовать прокси для удержания более узкой области действия от более широкой области действия (например, прототип из синглтона). Все, что вам нужно, это определить компонент прототипа с соответствующей областью действия и proxyMode. Вы можете прочитать о прокси области действия * 1001.* здесь .

2) Еще одна вещь, которую я заметил, - это то, что вы планируете использовать несколько автопроводных аннотаций.обратите внимание, что вы можете использовать autowire в списке интерфейсов, и он автоматически подключит все компоненты, которые реализуют этот интерфейс, как обсуждено здесь .

Более того, вы можете добавить идентификатор платформы в интерфейс VehicleBuilder, а затемсгенерировать карту в конструкторе, например:

Map<Integer, VehicleBuilder> vehicleBuilders;
@Autowired
public VehicleBuilderFactory(List<VehicleBuilder> vehicleBuilders) {
   this.vehicleBuilders = vehicleBuilders.stream()
        .collect(Collectors(x -> x.getPlatformId(), x -> x));
}

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

0 голосов
/ 26 мая 2011

Не вдаваясь в подробности, вы говорите, что хотите производить компоненты-прототипы из синглтона, возможно, с поиском в контейнере IoC.

Раздел 3.4.6.1 Внедрение метода поиска в Spring Документация описывает, как это можно сделать, не теряя Инверсию Контроля, т. Е. Ваши компоненты не знают о хранилище бинов.

Я использовал ServiceLocatorFactoryBean для решения аналогичной проблемы раньше. Класс Javadoc класса превосходен и содержит несколько наглядных примеров.

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