如何指定抽象类的具体实现的哪个版本在Spring中自动装配?

时间:2018-12-10 16:28:00

标签: java spring dependency-injection abstract-class autowired

具有以下类结构:

public abstract class A {
    String someProperty = "property"

    public abstract void doSomething();
}

@Service
public class Aa extends A {

    @Override
    public abstract void doSomething() {
        System.out.println("I did");
    }
}

@Service
public class Ab extends A {

    @Override
    public abstract void doSomething() {
        System.out.println("I did something else");
    }
}

我需要一种方法,根据 properties 中的属性,告诉Spring我的 Foo 服务中的哪个A具体类Autowire文件。

@Service
public class Foo {

    @Autowire
    private A assignMeAConcreteClass;
}

在我的properties文件中,我有这个:

should-Aa-be-used: {true, false}

2 个答案:

答案 0 :(得分:2)

删除@Service批注,而在配置类中写入@Bean-annotated method,该类读取属性并返回适当的A实例。

答案 1 :(得分:1)

这不是一种新方法,但是对于您而言,我认为一种可能的合适方法是使用 想要有条件地注入bean的类中的FactoryBean
这个想法很简单:通过使用要注入的bean的接口对其进行参数化来实现FactoryBean并覆盖getObject()以注入希望的实现:

public class FactoryBeanA  implements FactoryBean<A> {   

    @Autowired
    private ApplicationContext applicationContext;

    @Value("${should-Aa-be-used}")
    private boolean shouldBeUsed;

    @Override
    public A getObject() {

        if (shouldBeUsed) {
            return applicationContext.getBean(Aa.class));

        return applicationContext.getBean(Ab.class));

    }
}

但是FactoryBean实例不是经典bean。您必须专门配置它。

您可以通过以下方式在Spring Java配置中对其进行配置:

@Configuration
public class FactoryBeanAConfiguration{

    @Bean(name = "factoryBeanA")
    public FactoryBeanA factoryBeanA() {
         return new FactoryBeanA();
    }

    @Bean
    public beanA() throws Exception {
        return factoryBeanA().getObject();
    }
}