javaspringspring-bootjavabeans

How does one get around the "first letter lowercase" limitation in the `@Qualifier` annotation in Spring?


MRE:

Controller:

@RestController
public class DITestRestController {

        private Language language;

        @Autowired
        public DITestRestController(@Qualifier("haskell") Language language) {
                this.language = language;
        }

        @GetMapping("/lang")
        public String getLanguage() {
                return language.name();
        }
}

C.java:

package com.testprojects.ditestproject;

import org.springframework.stereotype.Component;

@Component
public class C implements Language {

        @Override
        public String name() {
                return "C";
        }
}

Haskell.java

package com.testprojects.ditestproject;

import org.springframework.stereotype.Component;

@Component
public class Haskell implements Language {

        @Override
        public String name() {
                return "Haskell";
        }
}

haskell.java:

package com.testprojects.ditestproject;

import org.springframework.stereotype.Component;

@Component
public class haskell implements Language {

        @Override
        public String name() {
                return "haskell";
        }
}

error:

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'haskell' for bean class [com.testprojects.ditestproject.haskell] conflicts with existing, non-compatible bean definition of same name and class [com.testprojects.ditestproject.Haskell]

I feel this is because @Qualifier annotation requires that the first letter of the bean be lowercase to refer to the actual bean (@Qualifier("myClass") refers to a bean with name MyClass). Is there any way to get around this limitation?


Solution

  • You need to set the qualifier name in the class that you are defining.

    Either:

    @Component("haskellLower") 
    public class haskell...
    ...
    

    or

    @Component
    @Qualifier("haskellLower")
    public class haskell...
    

    You name the component before using it. And then you can call it also using the qualifier annotation:

    @Autowired
    public DITestRestController(@Qualifier("haskellLower") Language language) {
        this.language = language;
    }
    

    From OP: Point to be noted, Just doing @Component("Haskell") on just one worked and haskell automatically referred to the other