web-dev-qa-db-fra.com

Spring attendait au moins 1 bean qui se qualifie comme candidat autowire pour cette dépendance

J'ai un problème avec cet Autowire:

@Controller
public class ChiusuraController {

    @Autowired
    private ChiusuraProvider chiusuraProvider;
}

avec ce haricot:

@Service @Transactional
public class ChiusuraProvider extends ThreadProvider {


    public void run() {}
}

qui s'étend

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

Je reçois cette erreur:

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)}

J'ai vu que je n'ai pas eu cette erreur si je supprime étend ThreadProvider de la classe auto-câblée, mais j'ai vraiment besoin de la classe abstraite ThreadProvider.

18
Tobia

S'il y a une interface n'importe où dans la hiérarchie ThreadProvider, essayez de mettre le nom de l'interface comme type de votre fournisseur de services, par exemple. si vous avez dit cette structure:

public class ThreadProvider implements CustomInterface{
...
}

Ensuite, dans votre contrôleur, essayez ceci:

@Controller
public class ChiusuraController {

    @Autowired
    private CustomInterface chiusuraProvider;
}

La raison pour laquelle cela se produit est, dans votre premier cas, lorsque vous DID N'avez PAS ChiusuraProvider étendre ThreadProvider Spring était probablement sous-jacent à la création d'un proxy basé sur CGLIB pour vous (pour gérer la @Transaction).

Lorsque vous DID étendez à partir de ThreadProvider en supposant que ThreadProvider étend une certaine interface, Spring dans ce cas crée un Java Dynamic Proxy based Proxy, qui serait semblent être une implémentation de cette interface au lieu d'être de type ChisuraProvider.

Si vous devez absolument utiliser ChisuraProvider, vous pouvez essayer AspectJ comme alternative ou forcer un proxy basé sur CGLIB dans le cas avec ThreadProvider également de cette façon:

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

Voici quelques références supplémentaires à ce sujet sur le site de référence de printemps: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html # classic-aop-pfb

18
Biju Kunjummen

Vous devez mettre cette ligne dans votre contexte d'application:

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

En savoir plus sur Détection automatique des classes et enregistrement des définitions de bean dans la documentation .

7
Xaerxess