简体   繁体   中英

Spring creates twice a child bean on inheritance and never creates parent bean

I have such configuration:

  @Configuration
  public class A {

    @Bean("A")
    public WebServiceTemplate webServiceTemplate() throws Exception {
        return createTemplate();
    }

    WebServiceTemplate createTemplate() throws Exception {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setDefaultUri(url_01); 
       ..........
       .........
        return webServiceTemplate;
    }
  }


  @Configuration
  public class B extends A {

    @Bean("B")
    public WebServiceTemplate anotherWebServiceTemplate() throws Exception {
      WebServiceTemplate template = createTemplate();
      template.setDefaultUri(url_02);
      return template;
    }
  }

The problem is that Spring autowires @Bean("B") twice: when I autowire it with @Qualifier("A") and when I autowire it with @Qualifier("B"):

  @Qualifier("A")
  private @Autowired WebServiceTemplate template; (here is template with url_02)
    
  @Qualifier("B")
  private @Autowired WebServiceTemplate template; (here is template with url_02)

In debug mode I see that Spring creates @Bean("B") twice and never creates @Bean("A")

anotherWebServiceTemplate uses the same object generated by createTemplate , that the reason why you really have the same content in both ones (really you have only one object).

You should create again a new instance with the desired configuration for the second one. Spring by default uses Singleton for their beans so you will have only 2 instances of WebServiceTemplate .

Not sure why you need inheritance to work with templates, but in any case, you can adapt the following "example code" in an easy way:

@Configuration
public class TemplatesConfiguration {

  @Bean
  @Primary
  @Qualifier("defaultTemplate")
  public WebServiceTemplate createTemplate() {
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setDefaultUri("url_01");
    ...
    return webServiceTemplate;
  }

  @Bean
  @Qualifier("anotherTemplate")
  public WebServiceTemplate anotherWebServiceTemplate() {
    // Create a new object instead use the one generated in createTemplate method
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setDefaultUri("url_02");
    ...
    return webServiceTemplate;
  }

}

Example of a class that uses both:

@Service
public class TemplatesService {

  @Autowired
  @Qualifier("defaultTemplate")
  private final WebServiceTemplate template1;

  @Autowired
  @Qualifier("anotherTemplate")
  private final WebServiceTemplate template2;

  ...
}

In this case, template1 and template2 will contain the "desired string" (and any other specific configuration).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM