自从Spring 3.0升级到Spring 3.1以来,NoSuchBeanDefinitionException不一致

时间:2014-02-05 02:31:27

标签: java spring autowired

自从从Spring 3.0升级到Spring 3.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代码(删除了不相关的代码):

public class ExecutionEnvironmentImpl extends ExecutionEnvironment {

    @Autowired
    @Qualifier("functionThreadPool")
    private ListeningExecutorService functionThreadPool;

    public ExecutionEnvironmentImpl() {
    }

    public void setFunctionThreadPool(ListeningExecutorService functionThreadPool) {
        this.functionThreadPool = functionThreadPool;
    }

}

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

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">

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

<!-- 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>

限定符注释不再使用,因为我们没有定义其他ListeningExecutorService但我不相信它应该导致任何问题。

可能导致此问题的任何想法?我一直在考虑完全取消自动装配,但我想先了解为什么会发生这种情况。

谢谢!

2 个答案:

答案 0 :(得分:0)

这可能是Spring在应用程序上下文中引入bean的顺序中与时序相关的问题。可能值得明确告诉Spring首先创建functionThreadPool以确保它可以自动连接到executionEnvironment。为此,您可以使用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>

如果您打算使用自动装配,那么配置中也应该有<context:annotation-config>元素 - 以便Spring知道将functionThreadPool自动装入executionEnvironment

答案 1 :(得分:0)

尝试依赖,甚至直接连接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注释。

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