首页 > 解决方案 > 具有范围 PROTOTYPE 的 Spring 循环依赖

问题描述

我创建了下面的场景来了解 Spring 循环依赖。

当范围是单例时它是干净的。但是当 S COPE 是 PROTOTYPE 时就会发生冲突。

所以我想知道 Spring 是否支持避免以下情况,或者我们应该改变设计。如果是这样,请提出一些设计。

考虑下面的例子。

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BeanB {

    private BeanA beanA;

    @Autowired
    public void setBeanA(BeanA beanA) {
        this.beanA = beanA;
    }

    public void printBeanB() {
        System.out.println(getBeanName());
    }

    public void printBeanBBeanA() {
        System.out.println(getBeanName() + " - " + beanA.getBeanName());
    }

    public String getBeanName() {
        return "Bean B";
    }
}


@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BeanA {

    private BeanB beanB;

    @Autowired
    public void setBeanB(BeanB beanB) {
        this.beanB = beanB;
    }

    public void printBeanA() {
        System.out.println(getBeanName());
    }

    public void printBeanABeanB() {
        System.out.println(getBeanName() + " - " + beanB.getBeanName());
    }

    public String getBeanName() {
        return "Bean A";
    }
}

这是一个错误:

描述:

应用上下文中一些bean的依赖形成了一个循环:

demoApplication(字段私有 com.example.demo.beans.BeanA com.example.demo.DemoApplication.beanA)

那么Spring支持是避免这种情况还是我们应该改变设计。如果是这样,请提出一些设计。

标签: javaspringdependency-injectioncircular-dependencyspring-bean

解决方案


我可以通过使用@Lazy 注释来解决这个问题,如下所示。

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BeanA {

    @Autowired
    @Lazy
    private BeanB beanB;
    public void printBeanA() {
        System.out.println(getBeanName());
    }

    public void printBeanABeanB() {
        System.out.println(getBeanName() + " - " + beanB.getBeanName());
    }

    public String getBeanName() {
        return "Bean A";
    }
}

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BeanB {

    @Autowired
    @Lazy
    private BeanA beanA;

    public void setBeanA(BeanA beanA) {
        this.beanA = beanA;
    }

    public void printBeanB() {
        System.out.println(getBeanName());
    }

    public void printBeanBBeanA() {
        System.out.println(getBeanName() + " - " + beanA.getBeanName());
    }

    public String getBeanName() {
        return "Bean B";
    }
}

推荐阅读