自从从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但我不相信它应该导致任何问题。
可能导致此问题的任何想法?我一直在考虑完全取消自动装配,但我想先了解为什么会发生这种情况。
谢谢!
答案 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注释。
我们没有真正解决问题,但更像是避免它。我希望我能提供更好的答案。