Можно ли в Spring Autowire один и тот же экземпляр класса с прототипом в двух местах? - PullRequest
4 голосов
/ 03 февраля 2010

** изменил пример, чтобы лучше выразить ситуацию

Я использую пружину 2.5 и имею следующую ситуацию

@Component
@Scope("prototype") 
Class Foo
{
}

class A
{ 
  @Autowired 
  Foo fooA;
}


class B
{ 
  @Autowired 
  Foo fooB;
}



class C
{ 
  @Autowired 
  Foo fooC;
}

Я пытаюсь понять, есть ли способ использовать @Autowired и привязать тот же экземпляр FOO к fooA и fooB при привязке другого экземпляра к fooC

Я понимаю, что если область действия FOO будет singleton, она будет работать

но я брожу, если есть способ достичь той же цели, используя область действия protoype.

также, пожалуйста, объясните, является ли это правильным использованием концепции автопроводки? пытаюсь ли я злоупотребить целью рамок весны

Ответы [ 3 ]

5 голосов
/ 03 февраля 2010

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

В контексте веб-приложения есть готовое решение - используйте request scope - таким образом, в каждом цикле запроса / ответа у вас будет только один экземпляр вашего компонента, независимо от того, где и сколько раз вы вводите его.

В контексте не веб-приложения вы можете определить собственную реализацию org.springframework.beans.factory.config.Scope

Обновление: после того, как вы пояснили, это выглядит как очень странный случай.Мне приходит в голову следующее:

  • определяют два FactoryBean с (на самом деле - подклассы AbstractFactoryBean) - один каждый раз возвращает новый объект, а другой возвращает один и тот же объект (обаони должны находиться в области singleton
  • вводить Foo с @Resource(name="prototypeFactoryBean") и @Resource(name="singletonFactoryBean") (вместо @Autowired)
  • singletonFactoryBean может быть разработан дляпросто верните синглтон (внедренный в класс фабричного компонента)
  • prototypeFactoryBean может создать новый экземпляр, приведите BeanFactory (доступно через getBeanFactory()) к AutowireCapableBeanFactory и вызовите .autowire(newlyCreatedBean),а затем верните его.(в качестве альтернативы вы можете ввести ApplicationContext и получить AutowireCapableBeanFactory)

Но это слишком сложно, и вам понадобятся расширенные знания о пружине даже после моего объяснения:)

Более тогоЯ думаю, вам следует пересмотреть свой дизайн, вместо того, чтобы делать вышеперечисленные «причуды»

Обновление 2: После вашего комментария концепция именования переносится в аннотации - как я указал выше, вы можете использовать @Resource(name="someBean")

1 голос
/ 03 февраля 2010

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

С другой стороны, вы используете сканирование компонентов и автоматическую разводку.

1 голос
/ 03 февраля 2010

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

Кроме того, автоматическое подключение bean-объекта с прототипом сомнительно, с точки зрения дизайна (на самом деле, я бы слегка удивился, если бы это даже было разрешено).Обычная идея состоит в том, чтобы автоматически связывать вместе бины одной и той же области (есть способы обойти это, но здесь это не актуально).

Все в вашем дизайне говорит о том, что Foo не должен быть прототипом - почему вы сделали это так?

...