Есть ли способ повторно использовать <util: list> в файле конфигурации Spring?

У меня есть набор правил, которые нужно внедрить в набор классов, как показано ниже:

<bean id="rule1" class="com.vikdor.rules.Rule1" />
<bean id="rule2" class="com.vikdor.rules.Rule2" />
<bean id="rule3" class="com.vikdor.rules.Rule3" />
<bean id="rule4" class="com.vikdor.rules.Rule4" />
<bean id="rule5" class="com.vikdor.rules.Rule5" />

<util:list id="commonRules">
    <ref bean="rule1" />
    <ref bean="rule3" />
    <ref bean="rule5" />
</util:list>

<util:list id="normalInvRules">
   <!-- Include common rules -->
   <ref bean="rule4" />
</util:list>

<util:list id="prepaidInvRules">
   <!-- Include common rules -->
   <ref bean="rule2" />
</util:list>

Как я могу включить список общих правил в списки, соответствующие normalInvRules а также prepaidInvRules?

Количество правил (например, rule1, rule2 и т. Д.) Больше, а количество групп (normalInvRules, prepidInvRules и т. Д.) Также больше. Итак, мне интересно, есть ли способ избежать повторения общих правил и просто перечислить только конкретные и включить ссылку на общий список.

4 ответа

Решение

Существует функция, называемая "слияние коллекций", которая делает именно это. Смотрите раздел 3.3.3.4.1. "Слияние коллекций" в документации Spring или в блоге 2008 года (с примером), который я написал на эту тему.

Мне нравится подход, предложенный @GreyBeardedGeek, просто хочу добавить еще несколько предложений:

а. Делать это с помощью @Configuration со списком базовых правил в xml:

@Configuration
@ImportResource("classpath:/baseconfig.xml")
public static class RulesConfiguration{
    @Resource List<Rule> commonRules;

    @Bean
    public List<Rule> normalInvRules(){
        List<Rule> rules = new ArrayList<Rule>();
        rules.addAll(commonRules);
        rules.add(new Rule());
        return rules;
    }
}

б. Использование пользовательского фабричного компонента, отвечающего за расширение списка:

class ListExpandingFactoryBean<T> implements FactoryBean<List<T>>{

    private List<T> baseList;
    private List<T> extendedList;

    @Override
    public List<T> getObject() throws Exception {
        List<T> consolidatedList = new ArrayList<T>();
        consolidatedList.addAll(baseList);
        consolidatedList.addAll(extendedList);
        return consolidatedList;
    }

    @Override
    public Class<?> getObjectType() {
        return List.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
    public void setBaseList(List<T> baseList) {
        this.baseList = baseList;
    }

    public List<T> getExtendedList() {
        return extendedList;
    }

    public void setExtendedList(List<T> extendedList) {
        this.extendedList = extendedList;
    }

}

и используя это так:

<bean name="normalInvRules" class="ListExpandingFactoryBean" p:baseList-ref="commonRules">
    <property name="extendedList">
        <list>
            <ref bean="bean4"/>
        </list>
    </property>
</bean>

Спасибо за ответы. Вот как я, наконец, обратился к этому, используя Collection Merging:

<bean id="rule1" class="com.krovi.rules.Rule1" />
<bean id="rule2" class="com.krovi.rules.Rule2" />
<bean id="rule3" class="com.krovi.rules.Rule3" />
<bean id="rule4" class="com.krovi.rules.Rule4" />
<bean id="rule5" class="com.krovi.rules.Rule5" />

<bean id="commonList"
    class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
        <list>
            <ref bean="rule1" />
            <ref bean="rule2" />
            <ref bean="rule3" />
        </list>
    </property>
</bean>
<bean id="firstExecutorRules" parent="commonList"
    class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
        <list merge="true">
            <ref bean="rule4" />
        </list>
    </property>
</bean>
<bean id="secondExecutorRules" parent="commonList"
    class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
        <list merge="true">
            <ref bean="rule5" />
        </list>
    </property>
</bean>

Вы можете создать класс с общими правилами и автоматически связать их с другими правилами? Разве это не сработает?

Вы можете использовать тот же подход, используя конфигурацию XML, и внедрить его, используя атрибут ref.

Другие вопросы по тегам