Java Spring Bean依赖项注入conditionalOnBean

时间:2019-12-01 09:09:44

标签: java spring dependency-injection

试图创建一个类,该类将被JavaConfig用作bean定义的源。

@Configuration
public class MyClass {
    @Bean
    @ConditionalOnProperty(name = "property")
    public A fuction1() {
       doSomething1(); // may return an exception
    }

    @Bean
    @ConditionalOnMissingBean(name = "fuction1")
    public A fuction2() {
        doSomething2();
    }

    @Bean
    public B fuction3(A a) {
        doSomething3(a);
    }
}

第三个bean定义有错误"could not autowire. There is more than one bean of A type.",我如何告诉Spring尝试自动连接第一个A,如果缺少,则尝试第二个A,即按照所述的条件过程进行。希望这是有道理的。 谢谢!

4 个答案:

答案 0 :(得分:0)

您正在定义两个具有相同名称的bean,因此,自动装配问题显而​​易见。尝试在要赋予优先级的bean上使用@Primary

答案 1 :(得分:0)

这种方法怎么样?

MB/s

答案 2 :(得分:0)

也许此配置会有所帮助:

@Configuration
public class MyClass {
    @Bean
    @ConditionalOnProperty(name = "property")
    public A fuction1() {
        try {
            doSomething1(); // may return an exception
        } catch(Exception e) {
            return null;
        }
    }

    @Bean
    @ConditionalOnMissingBean(name = "fuction1")
    public A fuction2() {
        doSomething2();
    }

    @Bean
    public B fuction3(@Autowired(required = false) @Qualifier("function1") A a1, @Qualifier("function2") A a2) {
        if (a1 == null) {
            doSomething3(a2);
        } else {
            doSomething3(a1);
        }
    }
}

答案 3 :(得分:0)

您提供的示例代码在概念上是正确的。当然会有编译错误,但注释正确。

这是一个可以编译和运行的示例。

@Configuration
public class ConditionalConfiguration {

    public static class A {

        private final String name;

        public A(String name) {
            this.name = name;
        }
    }

    public static class B {

        private final A a;

        public B(A a) {
            this.a = a;
        }
    }

    @Bean
    @ConditionalOnProperty(name = "a1-property")
    public A a1() {
        return new A("a1");
    }

    @Bean
    @ConditionalOnMissingBean(A.class)
    public A a2() {
        return new A("a2");
    }

    @Bean
    public B b(A a) {
        System.out.println("########## " + a.name);
        return new B(a);
    }
}

将属性a1-property传递给应用程序时

./gradlew clean bootRun -i -Da1-property
########## a1

创建了豆a1

缺少该属性时

./gradlew clean bootRun -i
########## a2

创建了豆a2

通过添加bootRun

,确保将Gradle配置为将系统属性传递给build.gradle任务
bootRun {
    systemProperties System.properties
}

要与a1 bean名称分离,应使用bean类型的条件:@ConditionalOnMissingBean(A.class)而不是@ConditionalOnMissingBean(name = "a1")

如果在bean创建过程中期望出现异常,则是另一种情况。 当用@Bean注释的工厂方法引发异常时,Spring应用程序将以BeanInstantiationException崩溃。

因此,应使用工厂方法处理异常:

@Bean
@ConditionalOnProperty(name = "a1-property")
public A a1() {
    try {
        //return new A("a1");
        throw new RuntimeException("Sample exception");
    } catch (Exception e) {
        return fallbackA();
    }
}

@Bean
@ConditionalOnMissingBean(A.class)
public A a2() {
    return fallbackA();
}

private A fallbackA() {
    return new A("a2");
}
相关问题