ApplicationContext.getBean(Class clazz)与代理不兼容

min*_*das 8 java proxy aop spring

我在Spring中有一个bean定义,它是代理对应的,它可以在任何地方使用:

<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>
Run Code Online (Sandbox Code Playgroud)

这一切都运作良好; 而在Spring-v3之前的世界里,我就像使用它一样

ApplicationContext ctx = ...;
my.Interface foo = (my.Interface) ctx.getBean("my.Bean"); // cast is necessary
Run Code Online (Sandbox Code Playgroud)

在Spring 3中,可以进行类型安全查找,例如:

my.Interface foo = ctx.getBean(my.Interface.class);
Run Code Online (Sandbox Code Playgroud)

再次,这适用于普通的豆类,而对于代理的豆类,我得到的my.BeanTarget不是my.Bean.我试图内联my.BeanTarget(如Spring文档中所示)使其隐藏,但我得到的只是

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [my.Interface] is defined: expected single bean but found 0: 
Run Code Online (Sandbox Code Playgroud)

那么是否可以使用代理bean的类型安全bean查找,如果是 - 如何?

ska*_*man 6

这里的问题是scope="prototype"你的问题ProxyFactoryBean.

上下文只会急切地初始化单例bean定义.非单一范围的豆只在被要求时才被初始化.这意味着,当你问一个给定类型的豆方面,上下文不能以要求他们类型初始化这些非单豆,它具有纯粹继续在bean定义的信息.

在这种情况下ProxyFactoryBean,生成的代理的类型由需要完全初始化bean的复杂逻辑确定.如果没有初始化,ProxyFactoryBean则只能将目标类型报告为null.

除了使用单例bean定义,或者通过名称明确要求bean,我不能说出这个方法,例如

<bean id="my.Interface"> class="ProxyFactoryBean"... >
Run Code Online (Sandbox Code Playgroud)

然后:

ctx.getBean(MyInterface.class.getName());
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用bean名称的约定作为它们实现的接口.