Spring MVC @Autowire不工作 - 循环依赖?

时间:2012-02-24 15:27:57

标签: java spring spring-mvc web.xml

这是我的xml配置:

<bean id="diameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" scope="singleton" init-method="start">
    <constructor-arg index="0"><value>${pcca.host}</value></constructor-arg>      
    <constructor-arg index="1"><value>${pcca.port}</value></constructor-arg>      
    <constructor-arg index="2" value="com.rory.djgx.message"/>
    <constructor-arg index="3" value="com.rory.djgx.avp"/> 
    <constructor-arg index="4">
    <list>
        <ref bean="asrHandler"/>
        <ref bean="aaaHandler"/>
        <ref bean="ceaHandler"/>
        <ref bean="dwaHandler"/>
        <ref bean="staHandler"/>
    </list>
    </constructor-arg> 
</bean>

<bean id="asrHandler" class="com.rory.ptspsim.messagereceivers.ASRHandler"/>
<bean id="aaaHandler" class="com.rory.ptspsim.messagereceivers.AAAHandler"/>
<bean id="ceaHandler" class="com.rory.ptspsim.messagereceivers.CEAHandler"/>
<bean id="dwaHandler" class="com.rory.ptspsim.messagereceivers.DWAHandler"/>
<bean id="staHandler" class="com.rory.ptspsim.messagereceivers.STAHandler"/>

这是ASRHandler类的开始:

public class ASRHandler implements DiameterMessageHandler
{   
    @Autowired
    private DiameterClient diameterClient;

有谁知道为什么这不起作用?我意识到处理程序类和DiameterClient类彼此依赖,但我虽然Spring负责这一点。

以下是日志中的消息:

org.springframework.beans.factory.BeanCreationException:在ServletContext资源[/WEB-INF/applicationContext.xml]中定义名称为'diameterClient'的bean时出错:在使用key设置构造函数参数时无法解析对bean'asrHandler'的引用[0];嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'asrHandler'的bean时出错:资源依赖注入失败;嵌套异常是org.springframework.beans.factory.BeanCurrentlyInCreationException:创建名为'diameterClient'的bean时出错:请求的bean当前正在创建:是否存在无法解析的循环引用?

谢谢!

2 个答案:

答案 0 :(得分:2)

这肯定是循环依赖。你应该看到Spring抛出的BeanCurrentlyInCreationException

在实例化Bean时,无法引用Bean。问题是您正在使用构造函数注入来创建bean。

我看到两件事应该可以解决这个问题。

  1. 根据DiameterClient的包名称,我假设它是一个你可以控制的类。我建议您使用xxxHandler类自动装配该类的所有依赖项。您甚至应该能够@Autowired List<DiameterMessageHandler>,Spring会将实现该接口的所有bean加载到列表中。
  2. 对您的bean使用基于属性的注入(而不是constructor-arg元素,请使用property元素。
  3. 修改

    如果你的文件看起来像这样:

    <bean id="diameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" scope="singleton" init-method="start"/>
    
    <bean id="asrHandler" class="com.rory.ptspsim.messagereceivers.ASRHandler"/>
    <bean id="aaaHandler" class="com.rory.ptspsim.messagereceivers.AAAHandler"/>
    <bean id="ceaHandler" class="com.rory.ptspsim.messagereceivers.CEAHandler"/>
    <bean id="dwaHandler" class="com.rory.ptspsim.messagereceivers.DWAHandler"/>
    <bean id="staHandler" class="com.rory.ptspsim.messagereceivers.STAHandler"/>
    

    和此:

    public class DiameterClient {
        @Autowired
        private List<DiameterMessageHandler> handlers;
    
        @Value("${pcca.host}")
        private String host;
    
        @Value("${pcca.port}")
        private int port; // or String...
    
        // I don't know what these other two would be...if they are autowired, or just values you would populate...
        private String somePackage;
    
        private String anotherPackage;
    
        // methods go here...
    }
    

    然后List<DiameterMessageHandler>将包含您在xml中的diameterClient bean下定义的5个bean。如果订单很重要,您可能需要按照特定顺序在上下文中指定它们,否则它应该正常工作。

    You could even take this further and annotate your classes with a Stereotype annotation (@Component most likely) and do a context:component-scan on the packages that contain these classes. That would mean even less xml declaration.

答案 1 :(得分:0)

您是否使用@Component @Service,@ Repository或@Controller注释注释了您的类,实际上忘记了当Diameter客户端位于ASRHandler中时,您正在将ASRHandler连接到Diameter客户端,这是循环的, asr处理程序是否需要自己的直径客户端?