0
votes

I am working on a project with multiple spring configuration java classes. Many of them have beans from other config classes autowired in and then injected in the constructors of other beans.

To make this as flexible as possible, I have been using spring profiles to define which implementation of an interface to use in the case where multiple are available.

This works fine, but I was wondering if there was any way with Spring that you could define a default bean?

For example: If no bean of type Foo found on classpath, inject implementation Bar. Else, ignore Bar.

I have looked at this question: Spring 3: Inject Default Bean Unless Another Bean Present, and the solution shown with Java config would work fine if you knew the name of all of the beans, but in my case I will not know what the beans are called.

Does anybody know of a way this can be achieved?

1

1 Answers

1
votes

Define the default as, well the default, just make sure that the name of the bean is the same, the one inside the profile will override the default one.

<beans>

    <!-- The default datasource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    </bean>

    <beans profile="jndi">
        <jndi:lookup id="dataSource" jndi-name="jdbc/db" />
    </beans>

</beans>

This construct would also work with Java based config.

 @Configuration
 public DefaultConfig {

      @Bean
      public DataSource dataSource() { ... }

      @Configuration
      @Profile("jndi")
      public static class JndiConfig {

          @Bean
          public DataSource dataSource() { ... // JNDI lookup }
      }

 }

When using java based configuration you can also specify a default and in another configuration add another bean of that type and annotate it with @Primary. When multiple instances are found the one with @Primary should be used.

@Configuration
public DefaultConfig {

     @Bean
     public DataSource dataSource() { ... }
}

@Configuration
@Profile("jndi")
public class JndiConfig {

    @Bean
    @Primary
    public DataSource jndiDataSource() { ... // JNDI lookup }
}