Java 报告了Spring假阳性循环依赖项

Java 报告了Spring假阳性循环依赖项,java,spring-mvc,Java,Spring Mvc,当依赖项顺序如下所示时,Spring报告假阳性循环依赖项错误 <bean id="water" class="java.lang.String"> <constructor-arg value="water"/> </bean> <bean id="animalFeeder" class="org.test.spring.autowire.impl.AnimalFeederImpl" autowire="constructor"/>

当依赖项顺序如下所示时,Spring报告假阳性循环依赖项错误

 <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"/>
  • FactoryBean依赖于列表(例如AnimalFeeder)
  • AnimalFeeder取决于字符串列表
有趣的事情是

 <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"/>
  • 当spring实例化顺序更改时(即FactoryBean出现在AnimalFeeder之前),未观察到问题。但当动物饲料商来到FactoryBean之前,这个问题就被发现了
  • 只有当涉及FactoryBean时,才会发生这种情况。当使用SimpleBean类代替FactoryBean时,未观察到问题
  • 这是源代码

    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"/>
    
    公共接口馈线{
    空进料();
    }
    公共类AnimalFeederImpl实现了Feeder{
    私有列表馈送类型;
    公共动物饲养模式(列出饲养类型){
    this.feedingTypes=feedingTypes;
    }
    @凌驾
    公共订阅源(){
    //喂这里
    }
    }
    公共类FeederManager{
    私人最终列表馈线;
    公共馈线管理器(列出馈线){
    这是。馈线=馈线;
    }
    //此方法将每4小时触发一次喂食
    public void triggerFeeding(){
    }
    }
    公共类FeederFactory实现FactoryBean,初始化Bean{
    私有列表馈线;
    私人FeederManager FeederManager;
    公用馈线工厂(列出馈线){
    这是。馈线=馈线;
    }
    @凌驾
    public void afterPropertieSet()引发异常{
    馈线管理器=新馈线管理器(馈线);
    }
    公共静态void main(字符串参数[]){
    ClassPathXmlApplicationContext上下文=新的ClassPathXmlApplicationContext();
    setAllowBeanDefinitionOverriding(false);
    setConfigLocation(“testapplicationcontext.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"/>
    
    
    
    谢谢

    问题(在看似不完整的示例中也会导致编译错误)在于
    federfactory
    实现了类型
    FactoryBean

     <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"/>
    
    public class FeederFactory implements FactoryBean, InitializingBean {
    
    当Spring试图使用构造函数实例化
    AnimalFeederImpl
    bean时

     <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"/>
    
    public AnimalFeederImpl(List<String> feedingTypes) {
        this.feedingTypes = feedingTypes;
    }
    

    这需要它实例化
    AnimalFeederImpl
    ,它已经在构建中,整个过程由于循环依赖性而失败。

    感谢您的快速回答。对不起,我有点懒得格式化所有的行,因此只粘贴了骨架。
     <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"/>