在春季

时间:2017-12-19 17:03:57

标签: java spring spring-boot

我不知道它是否得到支持,但我不小心@Import发现了一个没有@Configuration的弹簧配置。结果,我得到了一个神秘的循环依赖性错误,显然不是这种情况(或者至少我无法识别它)。这是错误消息,我不太了解:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanC' defined in URL[jar:file:/Users/ghornyak/work/dev/sandbox/spring-boot-tutorial/build/libs/gs-spring-boot-0.1.0.jar!/BOOT-INF/classes!/hello/BeanC.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hello.config.TestConfig': Unsatisfied dependency expressed through method 'beanB' parameter 0; nested exception is
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?

这是一个简化示例:BeanBBeanC取决于BeanABeanABeanBTestConfig类中定义缺少@Configuration注释。

配置来源:

package hello.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import hello.BeanA;
import hello.BeanB;

public class TestConfig {

    @Bean
    public BeanA beanA() {
        System.out.println("Creating beanA");
        return new BeanA();
    }

    @Bean
    @Autowired
    public BeanB beanB(BeanA beanA) {
        System.out.println("Creating beanB: " + beanA);
        return new BeanB();
    }
}

BeanC的定义:

package hello;

import org.springframework.stereotype.Component;

@Component
public class BeanC {

    public BeanC(BeanA beanA) {
        System.out.println("Creating BeanC: " + beanA);
    }
}

测试申​​请:

package hello;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

import hello.config.TestConfig;

@SpringBootApplication
@Import(TestConfig.class)
@ComponentScan(basePackageClasses = Application.class)
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

现在,如果我使用@Configuration注释标记配置,则错误消失,一切都按预期工作。所以问题是,如果导入的配置类有上述注释吗?如果是这样,那么为什么没有它表示错误?

1 个答案:

答案 0 :(得分:2)

是的,你不能在同一个类中的另一个bean定义中调用bean,除非用@Configuration注释该类,其背后的原因是cglib,它创建Spring需要引用的AOP代理并调用bean < / p>

  

通常,@ Node方法在@Configuration类中声明。   在这种情况下,bean方法可以引用其中的其他@Bean方法   同一个班直接打电话给他们。这确保了引用   bean之间是强类型和可导航的。这样所谓   “bean间引用”保证尊重范围和AOP   语义,就像getBean()查找一样。这些是语义   从最初的'Spring JavaConfig'项目中了解到它需要   CGLIB在运行时子类化每个这样的配置类。作为一个   结果,@ Configuration类和它们的工厂方法一定不能   在此模式下被标记为最终或私人

检查此link