Как указать, какая версия конкретной реализации для абстрактного класса будет автоматически подключена в Spring? - PullRequest
0 голосов
/ 10 декабря 2018

Имея следующую структуру классов:

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

Мне нужен способ сообщить Spring, какой A конкретный класс равен Autowire в моем Foo сервисе, на основе свойствав файле properties .

@Service
public class Foo {

    @Autowire
    private A assignMeAConcreteClass;
}

И в моем файле properties у меня есть это:

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

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Не новый способ, но в вашем случае я думаю, что возможным подходящим способом было бы использование FactoryBean в классе, который хочет вводить bean-компонент условно.
Идея проста: вы реализуете FactoryBean с помощьюпараметризация его с помощью интерфейса bean-компонента, который вы хотите внедрить и переопределить 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();
    }
}
0 голосов
/ 10 декабря 2018

Удалите аннотацию @Service, вместо этого напишите @Bean -аннотированный метод в классе конфигурации, который считывает свойства и возвращает соответствующий A экземпляр.

...