2015-04-01 5 views
2

Spring сообщают положительную ошибку ложной круговая зависимости, когда порядок зависимости выглядит, как показано нижеСпринг ложноположительной циклическая зависимость сообщила

  • FactoryBean зависит от списка (например, AnimalFeeder)
  • AnimalFeeder зависит от списка строк.

Интересные вещи

  1. Проблема не наблюдалось, когда порядок пружинный конкретизации изменения Ie) FactoryBean предшествует AnimalFeeder. Но проблема была замечена, когда AnimalFeeder приходит до FactoryBean.
  2. Это происходит только при использовании FactoryBean. проблема не наблюдалась, когда вместо FactoryBean использовался простой класс bean.

здесь исходный код

public interface Feeder { 
    void feed(); 
} 

public class AnimalFeederImpl implements Feeder { 
    private List<String> feedingTypes; 
    public AnimalFeederImpl(List<String> feedingTypes) { 
    this.feedingTypes = feedingTypes; 
    } 
    @Override 
    public void feed() { 
    //feed here 
    } 
} 

public class FeederManager { 
    private final List<Feeder> feeders; 
    public FeederManager(List<Feeder> feeders) { 
     this.feeders = feeders; 
    } 

    //This method will trigger the feeding for every 4 hours 
    public void triggerFeeding() { 
    } 
} 


public class FeederFactory implements FactoryBean, InitializingBean { 
    private List<Feeder> feeders; 
    private FeederManager feederManager; 
    public FeederFactory(List<Feeder> feeders) { 
     this.feeders = feeders; 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     feederManager = new FeederManager(feeders); 
    } 

    public static void main(String args[]){ 
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(); 
    context.setAllowBeanDefinitionOverriding(false); 
    context.setConfigLocation("test-application-context.xml"); 
    context.refresh(); 
    } 
} 

здесь контекст файла

<bean id="water" class="java.lang.String"> 
    <constructor-arg value="water"/> 
</bean> 
<bean id="animalFeeder" class="org.test.spring.autowire.impl.AnimalFeederImpl" autowire="constructor"/> 
<bean id="animalFeeder" class="org.test.spring.autowire.impl.AnimalFeederImpl" autowire="constructor"/> 
<bean id="feederMgr" class="org.test.spring.autowire.impl.FeederFactory" autowire="constructor"/> 

Спасибо!

ответ

1

Проблема (которая также вызывает ошибку компиляции в вашем, казалось бы, неполном примере), заключается в том, что ваш FeederFactory реализует тип FactoryBean.

public class FeederFactory implements FactoryBean, InitializingBean { 

Когда весна пытается создать экземпляр AnimalFeederImpl боб, используя конструктор

public AnimalFeederImpl(List<String> feedingTypes) { 
    this.feedingTypes = feedingTypes; 
} 

он должен сначала построить List<String> аргумент. Для этого нужно сканировать контекст для beans типа String. Он точно знает, что water является компонентом типа String, потому что он объявлен таким образом в конфигурации XML. Он точно знает, что AnimalFeederImpl не является компонентом типа String, потому что его класс также объявлен.

Для FeederFactory, однако, это немного отличается. Объявляя класс как подкласс FactoryBean, вы сообщаете Spring, что этот компонент может создавать bean-элементы другого типа. Чтобы узнать, какой тип, Spring нужно создать экземпляр типа FeederFactory и использовать его метод getObjectType.

Но его конкретизация требует Spring для autowire

public FeederFactory(List<Feeder> feeders) { 

, которая требует его экземпляр AnimalFeederImpl, который уже находится в строительстве, и все это терпит неудачу с круговой зависимости.

+1

Спасибо за быстрый ответ. Извините, мне было немного ленив, чтобы отформатировать все строки, отсюда только сложенный скелет. – Saravanan

Смежные вопросы