Объявление интерфейса bean-компонента Spring

У меня есть рабочий класс:

public class WorkClass implements ApplicationContextAware {
   ... // has access to ApplicationContext
}

Есть полезный интерфейс:

public interface UsefulInterface {
    void doUseful();
}

Имейте некоторый класс реализации, который может сделать гораздо больше:

public class CanDoAlmostEverything implements UsefulInterface {
    ...
}

Я хочу предоставить реализацию UsefulInterface (через CanDoAlmostEverything) для WorkClass с помощью Spring, но НЕ для доступа к каким-либо другим методам CanDoAlmostEverything, кроме "doUseful"

Другими словами, я хочу объявить свой bean [s] как:

<bean id="workerA" interface="UsefulInterface" class="CanDoAlmostEverything"/>
<bean id="workerB" interface="UsefulInterface" class="AnotherUsefulImpl"/>

WorkClass будет знать о реализации интерфейса только во время выполнения, и код должен выглядеть так:

String todayWorker = getWorkerNameFromDataBase();
UsefulInterface worker = appCtx.getBean(todayWorker, UsefulInterface.class);
worker.doUseful();

Является ли это возможным? И как это должно выглядеть?


person user2602807    schedule 13.07.2015    source источник


Ответы (1)


Я не рекомендую вам использовать getBean таким образом. В документации Spring написано, что это может плохо сказаться на производительности.

http://docs.spring.io/spring/docs/1.0.2/api/org/springframework/beans/factory/BeanFactory.html#getBean%28java.lang.String%29

Возвращает экземпляр (возможно, общий или независимый) данного имени компонента. Обеспечивает меру безопасности типов, вызывая исключение, если компонент не относится к требуемому типу.

Обратите внимание, что вызывающие объекты должны сохранять ссылки на возвращаемые объекты. Нет никакой гарантии, что этот метод будет реализован эффективно. Например, она может быть синхронизирована или может потребоваться выполнение запроса РСУБД.

Спросит родительскую фабрику, если компонент не может быть найден в этом экземпляре фабрики.

Это действительно зависит от того, что вы хотите сделать. Вы думали, что ваш Workclass может быть бобом?

public class WorkClass implements ApplicationContextAware {
    private UsefulInterface workerA;
    private UsefulInterface workerB;

    public void setWorkerA(UsefulInterface workerA) {
        this.workerA = workerA;
    }

    public void setWorkerB(UsefulInterface workerB) {
        this.workerB = workerB;
    }

    public void work() {
        UsefulInterface workerToUse;
        if(condition) {
            workerToUse = workerA;
        } else {
            workerToUse = workerB;
        }
        // treatment
    }
}

Вот файл конфигурации:

<bean id="workerA" interface="UsefulInterface" class="CanDoAlmostEverything"/>
<bean id="workerB" interface="UsefulInterface" class="AnotherUsefulImpl"/>
<bean id="mainWorker" class="package.of.WorkClass">
     <property name="workerA" ref="workerA" />
     <property name="workerB" ref="workerB" />
</bean>

Ваш основной класс должен будет вызвать getBean, но только один раз, чтобы получить экземпляр WorkClass.

person Thomas Betous    schedule 13.07.2015