如果我在Java配置中覆盖了bean定义,将会发生什么?

时间:2018-11-11 04:09:21

标签: java spring mongodb configuration override

使用Spring Data Mongodb开发时,我想在MongoDB配置中进行一些自定义。 通常,我将扩展AbstractMongoConfiguration并实现抽象方法。当前, AbstractMongoConfiguration 类具有以下内容:

@Configuration
public abstract AbstractConfiguration extends MongoConfigurationSupport {
    public abstract MongoClient mongoClient();

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
          return new MongoTemplate(mongoDbFactor(), mappingMongoConverter());

    ....   
}

扩展此类时,我想自定义bean MongoTemplate ,所以我想重写 mongoTemplate 方法,这行得通吗?

@Configuration
public MongoConfiguration extends AbstractConfiguration {
    public MongoClient mongoClient(){
        ....
    }

    @Override
    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
          MongoTemplate template = super.mongoTemplate();
          template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
    }

    ....   
}

2 个答案:

答案 0 :(得分:0)

在这种情况下,您正在使用@Override的事实与覆盖Spring Bean的概念没有直接关系。 Spring通过名称来跟踪bean,并且可以用另一个具有相同名字的bean来替换它-并不经常使用,但是有时有必要解决棘手的情况。 @Override特别是Java继承位。

在您的情况下,您的设置应该可以按预期工作,因为当Spring实例化bean时,它将调用MongoConfiguration#mongoTemplate()。如果定义在不同的类中,则它们都将产生名为mongoTemplate的bean,最后一个被评估的对象将获胜(有一些技巧可以通过使用@Order或注入其他配置来明确地控制它) ,但这并不理想)。

请注意,在这种特定情况下,您可能更喜欢使用Spring Boot自动配置,在这种情况下,您将不会覆盖Java方法。相反,您可以注入MongoTemplate并只需在其上调用setter方法即可,方法是编写ApplicationRunner或侦听ContextRefreshedEvent

答案 1 :(得分:0)

最近有一个非常相似的问题。

有2种情况:

情况1:没有限定词的情况下覆盖

@Configuration
public MongoConfiguration extends AbstractConfiguration {
    public MongoClient mongoClient(){
        ....
    }

    @Override
    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
          MongoTemplate template = super.mongoTemplate();
          template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
    }

    ....   
}

在这种情况下,将使用覆盖的定义而不是父定义来注册Bean。另外,只能注册1个豆

情况2:使用限定符覆盖

@Configuration
public MongoConfiguration extends AbstractConfiguration {
    public MongoClient mongoClient(){
        ....
    }

    @Override
    @Bean(name="myBean")
    public MongoTemplate mongoTemplate() throws Exception {
          MongoTemplate template = super.mongoTemplate();
          template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
    }

    ....   
}

在这种情况下,将创建 2个豆子({{1}和mongoTemplate)。但是,对于两个bean的创建,都将使用您覆盖的实现。