2012-02-24 1 views
1

Вот мой XML конфигурации:Spring MVC @Autowire не работает - круговая зависимость?

<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: Ошибка при создании боб с именем «diameterClient» определено в ServletContext ресурс [/WEB-INF/applicationContext.xml]: Не удается разрешить ссылку на bean 'asrHandler' при установке аргумента конструктора с ключом [0]; Вложенное исключение - org.springframework.beans.factory.BeanCreationException: Ошибка при создании bean-компонента с именем «asrHandler»: не удалось запустить инъекции ресурсов; Вложенное исключение - org.springframework.beans.factory.BeanCurrentlyInCreationException: Ошибка при создании bean с именем 'diameterClient': запрошенный bean-компонент в настоящее время находится в создании: существует ли неразрешимая круговая ссылка?

Спасибо!

+0

Там будет более поучительно каротаж где-то еще. Это скажет вам, что случилось. – skaffman

ответ

2

Это, безусловно, круговая зависимость. Вы должны увидеть BeanCurrentlyInCreationException, сброшенную весной.

Бобы не могут ссылаться при их создании. Проблема в том, что вы используете инъекцию конструктора для создания ваших компонентов.

Я вижу две вещи, которые должны быть в состоянии исправить это.

  1. На основании имени пакета DiameterClient Я предполагаю, что это класс, которым вы управляете. Я бы рекомендовал autowiring все зависимости этого класса, как у вас с вашими классами xxxHandler. Вы также должны быть в состоянии @Autowired a List<DiameterMessageHandler>, а Spring загрузит все bean s, которые реализуют этот интерфейс в списке.
  2. Используйте на основе свойств на основе ваших компонентов (вместо элемента constructor-arg используйте элемент property).

EDIT:

Если у вас есть файлы, выглядит примерно так:

<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> будет содержать 5 бобы, которые вы определили под своим ди ameterClient bean в вашем xml. Если порядок важен, вам может потребоваться указать их в вашем контексте в определенном порядке, но в противном случае он должен просто работать.

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.

+0

Спасибо - можете ли вы объяснить это немного с примером, если у вас его есть? «Вы даже должны иметь возможность @Autowired List , а Spring загрузит все компоненты, которые реализуют этот интерфейс в списке». – Rory

+0

@Rory проверить мои изменения. –

+0

Спасибо. Однако, похоже, проблема с настройкой свойств теперь: Не удалось преобразовать значение типа «java.lang.String» в требуемый тип «int»; Вложенное исключение - это java.lang.NumberFormatException: для строки ввода: «$ {pcca.port}» – Rory

0

Вы аннотировали свой класс с помощью @Component @Service, @Repository или аннотации @Controller, на самом деле забываете, что вы подключаете ASRHandler к Diameter-клиенту, когда Diameter-клиент находится в ASRHandler, это круговой , нужен ли обработчик asr для собственного клиента?