Spring预计至少有一个bean可以作为此依赖项的autowire候选者

Tob*_*bia 18 spring dependency-injection autowired

我在这个Autowire上遇到了麻烦:

@Controller
public class ChiusuraController {

    @Autowired
    private ChiusuraProvider chiusuraProvider;
}
Run Code Online (Sandbox Code Playgroud)

用这个bean:

@Service @Transactional
public class ChiusuraProvider extends ThreadProvider {


    public void run() {}
}
Run Code Online (Sandbox Code Playgroud)

延伸

public abstract class ThreadProvider extends Thread implements InitializingBean, Runnable, DisposableBean {
...
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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)}
Run Code Online (Sandbox Code Playgroud)

我看到我没有得到这个错误,如果我删除 autowired类的扩展ThreadProvider,但我真的需要ThreadProvider抽象类.

Bij*_*men 18

如果ThreadProvider层次结构中的任何地方都有接口,请尝试将接口的名称作为服务提供者的类型,例如.如果你说这个结构:

public class ThreadProvider implements CustomInterface{
...
}
Run Code Online (Sandbox Code Playgroud)

然后在您的控制器中试试这个:

@Controller
public class ChiusuraController {

    @Autowired
    private CustomInterface chiusuraProvider;
}
Run Code Online (Sandbox Code Playgroud)

发生这种情况的原因是,在您第一种情况下,当您没有ChiusuraProvider扩展ThreadProviderSpring时,可能是为您创建基于CGLIB的代理(处理@Transaction).

当您从ThreadProvider假设ThreadProvider扩展某个接口进行DID扩展时,Spring会在这种情况下创建一个基于Java动态代理的代理,它似乎是该接口的实现而不是ChisuraProvider类型.

如果您绝对需要使用ChisuraProvider,可以尝试使用AspectJ作为替代方法,或者使用ThreadProvider强制使用基于CGLIB的代理:

<aop:aspectj-autoproxy proxy-target-class="true"/>
Run Code Online (Sandbox Code Playgroud)

以下是Spring Reference网站上的更多参考资料:http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html#classic-aop -pfb


Xae*_*ess 7

您应该将此行放在应用程序上下文中:

<context:component-scan base-package="com.cinebot.service" />
Run Code Online (Sandbox Code Playgroud)

阅读有关在文档中自动检测类和注册bean定义的更多信息.