Java 从Spring 3.0升级到Spring 3.1后,NoSuchBeanDefinitionException不一致

Java 从Spring 3.0升级到Spring 3.1后,NoSuchBeanDefinitionException不一致,java,spring,autowired,Java,Spring,Autowired,自从从Spring3.0升级到Spring3.1以来,我们一直看到不一致的NoSuchBeanDefinitionException。这种情况只发生在大约2%的主机上,即使这样,问题在单个主机上也不一致,因为在重新启动同一台服务器后可能不会发生 以下是错误: nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.goog

自从从Spring3.0升级到Spring3.1以来,我们一直看到不一致的NoSuchBeanDefinitionException。这种情况只发生在大约2%的主机上,即使这样,问题在单个主机上也不一致,因为在重新启动同一台服务器后可能不会发生

以下是错误:

nested exception is org.springframework.beans.factory.BeanCreationException: Could 
not autowire field: private com.google.common.util.concurrent.ListeningExecutorService 
com.amazon.ms3.container.impl.ExecutionEnvironmentImpl.functionThreadPool; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No matching bean of type [com.google.common.util.concurrent.ListeningExecutorService] 
found for dependency: expected at least 1 bean which qualifies as 
autowire candidate for this dependency. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true), 
@org.springframework.beans.factory.annotation.Qualifier(value=functionThreadPool)} 
| at org.springframework.beans.factory.annotation
             .AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues...
下面是bean代码(删除了不相关的代码):

这是配置文件(删除了不相关的配置):


限定符注释不再有多大用处,因为我们没有定义其他ListingExecutorService,但我认为它不应该引起任何问题

你知道这是什么原因吗?我一直在考虑完全取消自动布线,但我想了解为什么会发生这种情况


谢谢

这可能与Spring在应用程序上下文中启动bean的顺序有关。首先明确告诉Spring创建
函数threadpool
,以确保它可以自动连接到
执行环境中,这可能是值得的。为此,您可以使用
depends-on
属性:

<bean id="executionEnvironment" 
      class="com.amazon.ms3.container.impl.ExecutionEnvironmentImpl" 
      scope="prototype"
      depends-on="functionThreadPool"/>

<!-- ThreadPool for executing tenant functions asynchronously -->
<bean id="functionThreadPool" class="com.google.common.util.concurrent.MoreExecutors" factory-method="listeningDecorator">
    <constructor-arg>
         <bean class="java.util.concurrent.Executors" factory-method="newCachedThreadPool"/>                     
     </constructor-arg>
    </bean>  
</beans>


如果您打算使用自动连接,那么您应该在配置中也有
元素,这样Spring就知道在尝试后将
函数threadpool
自动连接到
executionEnvironment

取决于甚至直接连接bean,如下所示:

<bean id="executionEnvironment" class="com.amazon.ms3.container.impl.ExecutionEnvironmentImpl" scope="prototype">
  <property name="functionThreadPool" ref="functionThreadPool"/>
</bean>

<!-- ThreadPool for executing tenant functions asynchronously -->
<bean id="functionThreadPool" class="com.google.common.util.concurrent.MoreExecutors" factory-method="listeningDecorator">
    <constructor-arg>
         <bean class="java.util.concurrent.Executors" factory-method="newCachedThreadPool"/>                     
     </constructor-arg>
</bean>  

在某些情况下,我们仍然看到同样的错误。唯一修复它的方法是删除ExecutionEnvironmentImpl类中的@Autowired注释


我们并没有真正解决这个问题,但更像是避免它。我希望我能提供一个更好的答案

Spring配置是否包含
元素?我在您提供的代码片段中没有看到,或者您在发布时删除了它?它没有。我过去玩过它,它没有任何区别,所以它被排除在外。您认为它在这里有帮助吗?Spring需要知道它应该将
函数threadpool
自动连接到
执行环境中。不过,我认为这是一个与时间有关的问题。将给出一个答案…一位同事说,他在混合XML和注释以及使用原型bean时注意到了类似的行为。因此我意识到注释后处理器设置在程序的另一部分,这就是为什么添加注释后处理器没有改变任何事。添加dependen可能会起作用,但我觉得这有点违背了目的,不如直接连接它。这样更可靠。我真的不想为每一个被注入的bean添加“dependens”,我同意——通常这是不必要的,因为Spring在注入之前会计算出依赖顺序。但是Spring在这种情况下可能无法做到这一点,因为
ExecutionEnvironment
并不直接依赖于
MoreExecutors
工厂,而是依赖于一个副作用,即
ListingExecutorService
对象的生成。Spring无法自动确定这一点,因此使用
依赖于
将强制执行它。实际上,functionThreadPool没有在其他任何地方使用,所以我想我将在ExecutionEnvironment配置中声明它。如果修好了,我会告诉你的。我只是担心类似的问题会在我们的配置中的其他地方出现。这也不起作用。即使在直接连接bean时,我们有时仍然会看到问题。解决这个问题的唯一办法是删除@Autowired注释。真奇怪。
<bean id="executionEnvironment" 
      class="com.amazon.ms3.container.impl.ExecutionEnvironmentImpl" 
      scope="prototype"
      depends-on="functionThreadPool"/>

<!-- ThreadPool for executing tenant functions asynchronously -->
<bean id="functionThreadPool" class="com.google.common.util.concurrent.MoreExecutors" factory-method="listeningDecorator">
    <constructor-arg>
         <bean class="java.util.concurrent.Executors" factory-method="newCachedThreadPool"/>                     
     </constructor-arg>
    </bean>  
</beans>
<bean id="executionEnvironment" class="com.amazon.ms3.container.impl.ExecutionEnvironmentImpl" scope="prototype">
  <property name="functionThreadPool" ref="functionThreadPool"/>
</bean>

<!-- ThreadPool for executing tenant functions asynchronously -->
<bean id="functionThreadPool" class="com.google.common.util.concurrent.MoreExecutors" factory-method="listeningDecorator">
    <constructor-arg>
         <bean class="java.util.concurrent.Executors" factory-method="newCachedThreadPool"/>                     
     </constructor-arg>
</bean>