Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot: "No qualifying bean of type... found" when autowiring concrete class

I am writing a component using Spring Boot and Spring Boot JPA. I have a setup like this:

The interface:

public interface Something {
    // method definitions
}

The implementation:

@Component
public class SomethingImpl implements Something {
    // implementation
}

Now, I have a JUnit test which runs with SpringJUnit4ClassRunner, and I want to test my SomethingImpl with this.

When I do

@Autowired
private Something _something;

it works, but

@Autowired
private SomethingImpl _something;

causes the test to fail throwing a NoSuchBeanDefinitionException with the message No qualifying bean of type [com.example.SomethingImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

But in the test case, I want to explicitly inject my SomethingImpl because it is the class I want to test. How to I achieve this?

like image 981
rabejens Avatar asked Mar 06 '15 08:03

rabejens


People also ask

How do I fix no qualifying bean of type?

The error is “expected at least 1 bean which qualifies as autowire candidate.” The solution is to add the injection class in the ApplicationContext using annotation @Component. The exception “NoSuchBeanDefinitionException: No qualifying bean of type” is resolved if the annotation @Component is added in the Lion class.

Does Spring @autowired inject beans by name or by type?

if Spring encounters multiple beans with same type it checks field name. if it finds a bean with the name of the target field, it injects that bean into the field.

Can I Autowire more than one bean?

When a bean implementation exists both in the production and test codes, IntelliJ will mark @Autowired instances of this bean as "cannot autowire, more than one bean...". This is of course incorrect, as the test implementation will never be deployed in a production environment.

How do I fix NoSuchBeanDefinitionException?

The best solution is to properly isolate beans. The DispatcherServlet is responsible for routing and handling requests so all related beans should go into its context. The ContextLoaderListener , which loads the root context, should initialize any beans the rest of your application needs: services, repositories, etc.


2 Answers

If you want a special bean you have to use the @Qualifier annotation:

@Autowired
@Qualifier("SomethingImpl")
private Something _something;
like image 183
Jens Avatar answered Sep 30 '22 22:09

Jens


I figured out you can do the same with a javax.inject style DI:

@Named("myConcreteThing")
public class SomethingImpl implements Something { ... }

Where you want to inject it:

@Inject
@Named("myConcreteThing")
private Something _something;

This is correctly picked up by @EnableAutoConfiguration and @ComponentScan.

like image 30
rabejens Avatar answered Sep 30 '22 22:09

rabejens