在模块项目中包含和覆盖相同bean id的bean属性

时间:2017-03-12 10:40:07

标签: java spring-mvc override spring-bean

我的问题是我应该为在群集环境中运行多个线程的Java Spring应用程序使用哪种配置策略。

应用程序的层次结构如下:

Main application files & config
|
|__Parent module files & config
   |
   |__Child module files & config

我有一个DataTravider,它是@Transactional:

@Transactional
public class DataProvider {

    protected Configuration configuration;

    public DataProvider(Configuration configuration, DummyArg1 arg1, DummyArg2 arg2) {
        this.configuration = configuration;
        createResult();
        addMoreStuffFromModules();
    }

    private void createResult() {
        this.result.setSomeStuff = "someStuff";
    }

    private void addMoreStuffFromModules() {
        this.result.setSomeMoreStuff = configuration.getModuleDataProvider.getData();
    }
}

主要应用程序配置:

<bean id="dataProvider" abstract="true" class="com.main.DataProvider">
        <constructor-arg ref="main-configuration"/>
        <constructor-arg ref="main-dummyArg1"/>
        <constructor-arg ref="main-dummyArg2"/>
</bean

<bean id="main-Configuration" class="com.main.Configuration" /> <!-- just an empty class in main application -->

父模块配置:

<bean id="dataProvider" abstract="true" class="com.main.DataProvider">
        <constructor-arg ref="parent-configuration"/>
        <constructor-arg ref="parent-dummyArg1"/>
        <constructor-arg ref="main-dummyArg2"/>
</bean

<bean id="parent-Configuration" class="com.parent.Configuration" /> 

如你所见。父模块需要为dataProvider和所有构造函数参数提供新bean,以便能够将自己的配置注入到Data Provider类中。 对于子模块,这是相同的:

<bean id="dataProvider" abstract="true" class="com.main.DataProvider">
        <constructor-arg ref="child-configuration"/>
        <constructor-arg ref="parent-dummyArg1"/>
        <constructor-arg ref="main-dummyArg2"/>
</bean

<bean id="child-Configuration" class="com.child.Configuration" /> 

这是一个好策略吗?我认为不是。因为如果父配置更新会发生什么(例如将配置设置为引用另一个bean)?然后我们希望子配置在constructor-arg。

中自动获取新的引用

我更愿意,如果它可能,让模块的配置只设置构造函数args,因为他们想要更改(而不是其他args),例如像这样:

<bean id="dataProvider" abstract="true" class="com.main.DataProvider">
        <constructor-arg ref="child-configuration"/>
        <!-- arg1 inherited from parent and/or main configuration -->
        <!-- arg2 inherited from parent and/or main configuration-->
</bean

<bean id="child-Configuration" class="com.child.Configuration" /> 

关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:1)

如果你使Configuration成为一个bean,你可以在子模块中覆盖那个bean,而不是覆盖DataProvider bean。

<强>更新

基于Java的配置示例,因为我不使用XML配置:

假设您有3个DataProvider需要的bean:

@Component
public class Configuration {
    // main config here
}

@Component
public class OtherData {
}

@Component
public class MoreData {
}

像这样的数据提供者:

@Component
public class DataProvider {
    @Inject private Configuration conf;
    @Inject private OtherData otherData;
    @Inject private MoreData moreData;
}

然后在你的其他模块中执行:

@Component @Primary
public class ChildConfiguration extends Configuration {
    // different config here
}

...您将只覆盖配置部分而不更改其他两个部分。