Spring ожидал по крайней мере 1 bean-компонент, который квалифицируется как кандидат автопроводки для этой зависимости.

У меня проблема с этим Autowire:

@Controller
public class ChiusuraController {

    @Autowired
    private ChiusuraProvider chiusuraProvider;
}

с этим бобом:

@Service @Transactional
public class ChiusuraProvider extends ThreadProvider {


    public void run() {}
}

что расширяет

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

Я получаю эту ошибку:

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

Я видел, что не получаю эту ошибку, если удаляю extends ThreadProvider из класса autowired, но мне действительно нужен абстрактный класс ThreadProvider.


person Tobia    schedule 04.07.2012    source источник


Ответы (2)


Если в иерархии ThreadProvider есть интерфейс, попробуйте указать имя интерфейса в качестве типа вашего поставщика услуг, например. если вы сказали эту структуру:

public class ThreadProvider implements CustomInterface{
...
}

Затем в вашем контроллере попробуйте следующее:

@Controller
public class ChiusuraController {

    @Autowired
    private CustomInterface chiusuraProvider;
}

Причина, по которой это происходит, заключается в том, что в вашем первом случае, когда у вас НЕ было ChiusuraProvider extend ThreadProvider, Spring, вероятно, лежал в основе создания для вас прокси-сервера на основе CGLIB (для обработки @Transaction).

Когда вы DID расширяетесь от ThreadProvider, предполагая, что ThreadProvider расширяет некоторый интерфейс, Spring в этом случае создает прокси-сервер на основе динамического прокси-сервера Java, который будет представлять собой реализацию этого интерфейса, а не тип ChisuraProvider.

Если вам абсолютно необходимо использовать ChisuraProvider, вы можете попробовать AspectJ в качестве альтернативы или принудительно использовать прокси на основе CGLIB в случае с ThreadProvider также следующим образом:

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

Вот еще несколько ссылок на этот вопрос с сайта Spring Reference: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html#classic-aop-pfb

person Biju Kunjummen    schedule 04.07.2012
comment
Что, если мой класс реализует несколько интерфейсов? - person user1050619; 05.11.2014
comment
Подожди... ты просто спас мне жизнь. Я использовал версию аннотации @EnableAspectJAutoProxy(proxyTargetClass = true) . Благодарю вас! - person Joao Polo; 22.12.2015

Вы должны поместить эту строку в контекст вашего приложения:

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

Подробнее о < em>Автоматическое обнаружение классов и регистрация определений bean-компонентов в документации.

person Xaerxess    schedule 04.07.2012
comment
Я добавил эту строку, где ChiusuraProvider включен в пакет com.cinebot.service, а ThreadProvider НЕ включен в этот пакет... но это не работает. - person Tobia; 05.07.2012
comment
Вы пробовали ответ @BijuKunjummen (используя прокси-сервер с областью действия AOP, не забудьте добавить зависимость CGLIB)? - person Xaerxess; 05.07.2012