JavaSpringbean依赖注入,conditionalOnBean

JavaSpringbean依赖注入,conditionalOnBean,java,spring,dependency-injection,Java,Spring,Dependency Injection,试图创建一个将由JavaConfig用作bean定义源的类 @Configuration public class MyClass { @Bean @ConditionalOnProperty(name = "property") public A fuction1() { doSomething1(); // may return an exception } @Bean @ConditionalOnMissingBean(nam

试图创建一个将由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定义出现错误
“无法自动连线。一个类型有多个bean。”
我如何告诉Spring尝试自动连线第一个A,如果缺少,则尝试第二个A,即按照所述的条件过程。希望这是有道理的。
谢谢

您正在使用相同的名称定义两个bean,因此,自动连接问题很明显。尝试在您想要优先处理的bean上使用
@Primary

这种方法怎么样

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

    @Bean
    @ConditionalOnProperty(name = "property", havingValue="false")
    public A fuction2() {
        doSomething2();
    }

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

此配置可能会有所帮助:

@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);
        }
    }
}

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

下面是一个编译并运行的示例

@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属性
传递给应用程序时

./gradlew clean bootRun -i -Da1-property
########## a1
创建bean
a1

当财产丢失时

./gradlew clean bootRun -i
########## a2
创建bean
a2

通过添加
build.Gradle

bootRun {
    systemProperties System.properties
}
要与
a1
bean名称解耦,使用bean类型上的条件:
@ConditionalOnMissingBean(A.class)
而不是
@ConditionalOnMissingBean(name=“a1”)

如果您期望在bean创建期间出现异常,则是另一种情况。 当用
@Bean
注释的工厂方法抛出异常时,Spring应用程序会因
BeanInstationException
而崩溃

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

@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");
}

我知道。我不想优先考虑其中一个。我希望它以bean是否存在为条件。bean 3仍然存在错误,因为在编译时仍然有两个autowire候选者,即使在运行时只有一个候选者?我不确定我是否理解。bean是在运行时连接的,而不是在编译时。。。。IDE并没有捕捉到这一点,但只要属性值是互斥的,代码实际上就会工作。。。