简体   繁体   中英

How to specify which version of a concrete implementation for an abstract class to autowire in Spring?

Having the following class structure:

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

I need a way to tell Spring which A concrete class to Autowire in my Foo service, based on a property in a properties file.

@Service
public class Foo {

    @Autowire
    private A assignMeAConcreteClass;
}

And in my properties file I have this:

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

删除@Service注释,而是在读取属性的配置类中编写@Bean -annotated方法 ,并返回相应的A实例。

Not a new way but in your case I think that a possible suitable way would be to use FactoryBean in the class that wants to inject the bean conditionally.
The idea is simple : you implement FactoryBean by parameterizing it with the interface of the bean that you want to inject and override getObject() to inject the wished implementation :

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

    }
}

But FactoryBean instances are not classic beans. You have to configure it specifically.

You could configure it in a Spring Java configuration in this way :

@Configuration
public class FactoryBeanAConfiguration{

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM