Search code examples
javaspringspring-bootdependency-injectionspring-config

How provide a different bean implementation to @Autowire field based on annotation?


I have a config class that provides two implemenations of the same base bean interface. I want these to be set on the autowired fields conditionally based on an annotation on the field.

public class MyController
{
    @Autowired
    private MyBeanInterface base;

    @Autowired
    @MyAnnotation
    private MyBeanInterface special;
}

This is a pesudo-code of the config class:

@Configuration
public class ConfigClass
{
    @Bean
    @Primary
    public MyBeanInterface getNormalBeanInterface()
    {
        return new MyBeanInterfaceImpl();
    }

    @Bean
    //This doesn't work
    @ConditionalOnClass(MyAnnotation.class)
    public MyBeanInterface getSpecialBeanInterface()
    {
        return new MyBeanInterfaceForMyAnnotation();
    }
}

How can I make the annotated field be populated by the second bean?


Solution

  • Use Qualifier annotation. Example:

    Controller:

    Add Qualifier annotation at the injected fields with bean id as parameter:

    public class MyController
    {
        @Autowired
        @Qualifier("normalBean")
        private MyBeanInterface base;
    
        @Autowired
        @Qualifier("specialBean")
        private MyBeanInterface special;
    }
    

    ConfigClass

    Specify bean id:

    @Configuration
    public class ConfigClass
    {
        @Bean(name="normalBean")
        @Primary
        public MyBeanInterface getNormalBeanInterface()
        {
            return new MyBeanInterfaceImpl();
        }
    
        @Bean(name="specialBean")
        public MyBeanInterface getSpecialBeanInterface()
        {
            return new MyBeanInterfaceForMyAnnotation();
        }
    }