ApplicationContext.getBean (Class clazz) не ' у меня хорошо работает с прокси

У меня есть определение bean-компонента в Spring и его прокси-аналог, который должен использоваться везде:

<bean name="my.Bean" class="org.springframework.aop.framework.ProxyFactoryBean" scope="prototype">
  <property name="proxyInterfaces" value="my.Interface"/>
  <property name="target" ref="my.BeanTarget"/>
  <property name="interceptorNames">
    <list>
      <value>someInterceptor</value>
    </list>
  </property>
</bean>

<bean name="my.BeanTarget" class="my.InterfaceImpl" scope="prototype">
  <property name="foo" ref="bar"/>
</bean>

Это все работает хорошо; и в pre-Spring v3 мире я использовал его как

ApplicationContext ctx = ...;
my.Interface foo = (my.Interface) ctx.getBean("my.Bean"); // cast is necessary

. В Spring 3 стало возможным делать безопасные поиски типов, например:

my.Interface foo = ctx.getBean(my.Interface.class);

Опять же, это хорошо работает для обычных bean-компонентов, тогда как для проксируемых bean-компонентов я получаю my.BeanTarget вместо my.Bean . Я попытался встроить мой. BeanTarget (как показано в документации Spring), чтобы сделать его скрытым, но все, что я получил, было

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [my.Interface] is defined: expected single bean but found 0: 

. Так возможно ли использовать поиск безопасных типов bean-компонентов с проксированными bean-компонентами, и если да - как?

8
задан skaffman 26 August 2010 в 13:34
поделиться

2 ответа

Проблема заключается в scope="prototype" в вашем ProxyFactoryBean.

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

В случае ProxyFactoryBean тип сгенерированного прокси определяется сложной логикой, требующей полной инициализации компонента. Без этой инициализации ProxyFactoryBean может сообщать о целевом типе только как null.

Я не могу сказать, как обойти это, кроме как использовать определение одноэлементного компонента или явно запрашивать компонент по имени, например.

<bean id="my.Interface"> class="ProxyFactoryBean"... >

а затем:

ctx.getBean(MyInterface.class.getName());

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

6
ответ дан 5 December 2019 в 18:55
поделиться

Похоже, область прокси, созданных ProxyFactoryBean, должна быть указана с использованием свойства singleton вместо атрибута scope:

<bean name="my.Bean" class="org.springframework.aop.framework.ProxyFactoryBean">  
    <property name="singleton" value="false"/>  
    ...
</bean>

Это решило проблему, когда целевой компонент является внутренним.

Если у вас есть несколько bean-компонентов верхнего уровня одного класса, вы можете использовать безопасный поиск по идентификатору:

my.Interface foo = ctx.getBean("my.Bean", my.Interface.class); 
2
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: