Emil D
Emil D

Reputation: 1904

How do I express a dependency on a bean defined in an imported configuration in Spring?

I recently started working at a place that uses Java configuration for Spring as opposed to XML and so far I'm loving it.

My question is the following:

If we have a @Configuration annotated class A that imports another @Configuration annotated class B, what is the proper, type-safe way for a bean defined in A to depend on a bean defined in B.

Here's an example I saw in a blog (https://blog.codecentric.de/en/2012/07/spring-dependency-injection-styles-why-i-love-java-based-configuration/):

@Configuration
public class PartnerConfig {

    @Bean
    public PartnerService partnerService() {
        return new PartnerServiceImpl();
    }

}

@Configuration
@Import(PartnerConfig.class)
public class CashingConfig {

    @Autowired
    private PartnerConfig partnerConfig;

    @Bean
    public CashingService cashingService() {
        return new CashingServiceImpl(partnerConfig.partnerService());
    }

}

As a second part to my question, if I was to do the above, would Spring interpret as a bean dependency? That is, when I do

partnerConfig.partnerService()

in the example above, am I getting Spring to fetch me the partnerService bean, or am I just calling a regular java method and creating a new instance of the PartherService (which is NOT what I want, since the bean should be a singleton) ?

EDIT: It has been suggested to use a @Qualifier. Would this work?

@Configuration
public class PartnerConfig {

    @Bean
    @MyCustomQualifier
    public PartnerService partnerService() {
        return new PartnerServiceImpl();
    }

}

@Configuration
@Import(PartnerConfig.class)
public class CashingConfig {

    @Bean
    public CashingService cashingService(@MyCustomQualifier PartnerService partnerService) {
        return new CashingServiceImpl(partnerService);
    }

}

Upvotes: 0

Views: 2485

Answers (2)

proulxs
proulxs

Reputation: 508

I recommend giving the docs a read: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html

Refer to the section:

@Bean Methods in @Configuration Classes

This sums it up very well.

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable.

Also take a look at: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html

Section:

Composing @Configuration classes

Upvotes: 2

M. Deinum
M. Deinum

Reputation: 124441

Just add the dependency as an argument to the @Bean annotated method and remove the autowiring of the configuration.

@Configuration
@Import(PartnerConfig.class)
public class CashingConfig {

    @Bean
    public CashingService cashingService(PartnerService partnerService) {
        return new CashingServiceImpl(partnerService);
    }

}

or simply autowire the PartnerService instead of the configuration.

@Configuration
@Import(PartnerConfig.class)
public class CashingConfig {

    @Autowire
    private PartnerService partnerService;

    @Bean
    public CashingService cashingService() {
        return new CashingServiceImpl(partnerService);
    }

}

Upvotes: 1

Related Questions