Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring expected at least 1 bean which qualifies as autowire candidate for this dependency

I have a trouble with this Autowire:

@Controller
public class ChiusuraController {

    @Autowired
    private ChiusuraProvider chiusuraProvider;
}

with this bean:

@Service @Transactional
public class ChiusuraProvider extends ThreadProvider {


    public void run() {}
}

that extends

public abstract class ThreadProvider extends Thread implements InitializingBean, Runnable, DisposableBean {
...
}

I get this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'chiusuraController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cinebot.service.ChiusuraProvider com.cinebot.web.controller.ChiusuraController.chiusuraProvider; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.cinebot.service.ChiusuraProvider] 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)}

I saw that I did not get this error if I remove extends ThreadProvider of autowired class, but I really need ThreadProvider abstract class.

like image 725
Tobia Avatar asked Jul 04 '12 15:07

Tobia


People also ask

How do you resolve expected at least one bean which qualifies as Autowire candidate?

Solution. 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 @ComponentScan. The spring boot main class should be as root package.

How do I fix Nosuchbeandefinitionexception?

This Issue occurs when the main class and repository class are in different packages and the repository class and interfaces are not automatically scanned. The solution is to annotate the main class with EnableJpaRepositories and explicitly mention the repository package that needs to be scanned.

Is @autowired used for dependency injection?

Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built on dependency injection and we inject the class dependencies through spring bean configuration file.

How do you Autowire a bean in XML?

Autowiring by property name. Spring container looks at the properties of the beans on which autowire attribute is set to byName in the XML configuration file. It then tries to match and wire its properties with the beans defined by the same names in the configuration file. Autowiring by property datatype.


2 Answers

If there is an interface anywhere in the ThreadProvider hierarchy try putting the name of the Interface as the type of your service provider, eg. if you have say this structure:

public class ThreadProvider implements CustomInterface{
...
}

Then in your controller try this:

@Controller
public class ChiusuraController {

    @Autowired
    private CustomInterface chiusuraProvider;
}

The reason why this is happening is, in your first case when you DID NOT have ChiusuraProvider extend ThreadProvider Spring probably was underlying creating a CGLIB based proxy for you(to handle the @Transaction).

When you DID extend from ThreadProvider assuming that ThreadProvider extends some interface, Spring in that case creates a Java Dynamic Proxy based Proxy, which would appear to be an implementation of that interface instead of being of ChisuraProvider type.

If you absolutely need to use ChisuraProvider you can try AspectJ as an alternative or force CGLIB based proxy in the case with ThreadProvider also this way:

<aop:aspectj-autoproxy proxy-target-class="true"/>

Here is some more reference on this from the Spring Reference site: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html#classic-aop-pfb

like image 111
Biju Kunjummen Avatar answered Sep 19 '22 12:09

Biju Kunjummen


You should put this line in your application context:

<context:component-scan base-package="com.cinebot.service" />

Read more about Automatically detecting classes and registering bean definitions in documentation.

like image 28
Xaerxess Avatar answered Sep 21 '22 12:09

Xaerxess