Условный справочник OSGI (ServiceMix) - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть два компонента b1 и b2 и логическое свойство myFlag. И b1, и b2 должны быть сконструированы, поскольку они используются в разных частях приложения. Иерархии классов b1 и b2 выглядят следующим образом:

interface MyFirstInterface { ... }

class B1Class implements MyFirstInterface { ... }

interface MySecondInterface extends MyFirstInterface { ... }

class B2Class implements MySecondInterface { ... }

В моем первом файле проекта у меня есть:

<service id="b1" interface="com.company.MyFirstInterface">
    <bean class="com.company.B1Class" />
</service>
<service id="b2" interface="com.company.MySecondInterface">
    <bean class="com.company.B2Class" />
</service>

Во втором файле чертежа у меня есть:

<cm:property-placeholder persistent-id="com.company.settings" update-strategy="reload">
    <cm:default-properties>
        <cm:property name="myFlag"/>
    </cm:default-properties>
</cm:property-placeholder>

<reference id="myBean" interface="com.company.MyFirstInterface">

Предположим, что я хочу:

  • myBean для обозначения b1, если и только если myFlag равно false и
  • myBean для обозначения b2, если и только если myFlag равно true.

Возможно ли это с учетом вышеуказанной конфигурации? Если да, что нужно сделать, чтобы это сработало?

Примечание: Я бы не хотел добавлять дополнительные свойства. Это не смертный приговор, если мне действительно нужно добавить один; Мне нужно решение этой проблемы независимо от удобства. myFlag просто оказывается существующим свойством в производственной системе, поэтому, если мне удастся придерживаться этого единственного свойства (которое напрямую связано с тем, какой бин должен быть выбран), это предпочтительнее.

1 Ответ

0 голосов
/ 08 ноября 2018

Если кто-то еще столкнется с этим, позвольте мне опубликовать решение, которое мы придумали.

Создайте две свои бобы

<bean id="b1" class="com.company.B1Class" />
<bean id="b2" class="com.company.B2Class" />

Создать фабричный класс

public class MyFactoryClass {
    private boolean myFlag;
    private B1Class b1;
    private B2Class b2;

    public MyFactoryClass(boolean myFlag, B1Class b1, B2Class b2) {
        this.myFlag = myFlag;
        this.b1 = b1;
        this.b2 = b2;
    }

    public MyFirstInterface buildIt() {
        return myFlag ? b2 : b1;
    }
}

Определите фабричный класс как компонент и используйте его для выбора класса

<bean id="myFactory" class="com.company.MyFactoryClass">
    <argument value="${myFlag}"/>
    <argument ref="b1"/>
    <argument ref="b2"/>
</bean>

<bean id="myBean" factory-ref="myFactory" factory-method="buildIt" />
<service id="myBean" interface="com.company.MyFirstInterface" />

Полные чертежи

Первый проект:

<cm:property-placeholder persistent-id="com.company.settings" update-strategy="reload">
    <cm:default-properties>
        <cm:property name="myFlag"/>
    </cm:default-properties>
</cm:property-placeholder>

<bean id="b1" class="com.company.B1Class" />
<bean id="b2" class="com.company.B2Class" />

<bean id="myFactory" class="com.company.MyFactoryClass">
    <argument value="${myFlag}"/>
    <argument ref="b1"/>
    <argument ref="b2"/>
</bean>

<bean id="myBean" factory-ref="myFactory" factory-method="buildIt" />
<service id="myBean" interface="com.company.MyFirstInterface" />

Второй проект:

<reference id="myBean" interface="com.company.MyFirstInterface" />
...