@ Autowired-没有找到符合依赖项类型的 bean

我通过使用 Spring 和 Hibernate 为服务创建实体、服务和 JUnit 测试来开始我的项目。这一切都很好。 然后,我添加了 spring-mvc,使用许多不同的分步教程来制作这个 Web 应用程序,但是当我试图使用 @Autowired注释来制作 Controller 时,我在部署过程中遇到了 Glassfish 的错误。我猜测由于某种原因 Spring 不能看到我的服务,但是在多次尝试之后我仍然不能处理它。

服务的测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml"})

还有

@Autowired
MailManager mailManager;

正常运作。

控制器没有 @Autowired也,我可以打开我的项目在网络浏览器没有麻烦。

/src/main/resources/beans.xml

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">


<context:property-placeholder location="jdbc.properties" />
    

<context:component-scan base-package="pl.com.radzikowski.webmail">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
    

<!--<context:component-scan base-package="pl.com.radzikowski.webmail.service" />-->
    

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
    

<!-- Persistance Unit Manager for persistance options managing -->
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource"/>
</bean>


<!-- Entity Manager Factory for creating/updating DB schema based on persistence files and entity classes -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="persistenceUnitName" value="WebMailPU"/>
</bean>


<!-- Hibernate Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--<property name="schemaUpdate" value="true" />-->
<property name="packagesToScan" value="pl.com.radzikowski.webmail.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
    

<!-- Hibernate Transaction Manager -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
    

<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="txManager"/>


</beans>

/webapp/WEB-INF/web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

/webapp/WEB-INF/mvc-patcher-servlet. xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    

<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
    

<mvc:annotation-driven/>
    

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
    

</beans>

网址: pl.com.radzikowski. webmail.service. AbstractManager

package pl.com.radzikowski.webmail.service;


import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;


/**
* Master Manager class providing basic fields for services.
* @author Maciej Radzikowski <maciej@radzikowski.com.pl>
*/
public class AbstractManager {


@Autowired
protected SessionFactory sessionFactory;


protected final Logger logger = Logger.getLogger(this.getClass());


}

Webmail.service 邮件管理器

package pl.com.radzikowski.webmail.service;


import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;


@Component
@Transactional
public class MailManager extends AbstractManager {
// some methods...
}

Pl.com.radzikowski.webmail. HomeController

package pl.com.radzikowski.webmail.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pl.com.radzikowski.webmail.service.MailManager;


@Controller
@RequestMapping("/")
public class HomeController {


@Autowired
public MailManager mailManager;


@RequestMapping(value = "/", method = RequestMethod.GET)
public String homepage(ModelMap model) {
return "homepage";
}


}

错误:

加载应用程序时发生异常
严重: 上下文/WebMail 解除部署失败
加载应用程序时发生异常: java.lang。IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.生命周期异常: org.springframework.beans.Factory。BeanCreationException: 创建名为“ homeController”的 bean 时出错: 自动连接依赖项注入失败; 嵌套异常是 org.springframework.beans.Factory。BeanCreationException: 无法自动连接字段: public pl.com.radzikowski.webmail.service。MailManager pl.com.radzikowski.webmail.controller.嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinition itionException: 没有符合条件的 bean 类型[ pl.com.radzikowski.webmail.service。找到依赖项: 预计至少有1个 bean 符合这个依赖项的自动连接候选项。依赖项注释: {@org。注释。自动连线(需求 = 真实)}

对于很多代码,我感到很抱歉,但是我不知道是什么原因导致了这个错误。

补充

我创建了这个界面:

@Component
public interface IMailManager {

附加工具:

@Component
@Transactional
public class MailManager extends AbstractManager implements IMailManager {

并且改变了自动连接:

@Autowired
public IMailManager mailManager;

但它仍然会抛出错误(当我尝试使用 @Qualifier时也是如此)

. . 无法自动线领域: 公共 网址: pl.com.radzikowski.webmail.service.IMailManager Webmail.controller. HomeController.mailManager...

我也试过 @Component@Transactional的不同组合。

我是否应该以某种方式在 web.xml 中包含 beans.xml?

732460 次浏览

The thing is that both the application context and the web application context are registered in the WebApplicationContext during server startup. When you run the test you must explicitly tell which contexts to load.

Try this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})

You should autowire interface AbstractManager instead of class MailManager. If you have different implemetations of AbstractManager you can write @Component("mailService") and then @Autowired @Qualifier("mailService") combination to autowire specific class.

This is due to the fact that Spring creates and uses proxy objects based on the interfaces.

Correct way shall be to autowire AbstractManager, as Max suggested, but this should work fine as well.

@Autowired
@Qualifier(value="mailService")
public MailManager mailManager;

and

@Component("mailService")
@Transactional
public class MailManager extends AbstractManager {
}

Can you try annotating only your concrete implementation with @Component? Maybe the following answer could help. It is kind of a similar problem. I usually put Spring annotations in the implementation classes.

https://stackoverflow.com/a/10322456/2619091

Spent much of my time with this! My bad! Later found that the class on which I declared the annotation Service or Component was of type abstract. Had enabled debug logs on Springframework but no hint was received. Please check if the class if of abstract type. If then, the basic rule applied, can't instantiate an abstract class.

I had this happen because my tests were not in the same package as my components. (I had renamed my component package, but not my test package.) And I was using @ComponentScan in my test @Configuration class, so my tests weren't finding the components on which they relied.

So, double check that if you get this error.

My guess is that here

<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

all annotations are first disabled by use-default-filters="false" and then only @Controller annotation enabled. Thus, your @Component annotation is not enabled.

I ran in to this recently, and as it turned out, I've imported the wrong annotation in my service class. Netbeans has an option to hide import statements, that's why I did not see it for some time.

I've used @org.jvnet.hk2.annotations.Service instead of @org.springframework.stereotype.Service.

If you are testing your controller. Don't forget to use @WebAppConfiguration on your test class.

This may help you:

I have the same exception in my project. After searching while I found that I am missing the @Service annotation to the class where I am implementing the interface which I want to @Autowired.

In your code you can add the @Service annotation to MailManager class.

@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {
  • One reason BeanB may not exist in the context
  • Another cause for the exception is the existence of two bean
  • Or definitions in the context bean that isn’t defined is requested by name from the Spring context

see more this url:

http://www.baeldung.com/spring-nosuchbeandefinitionexception

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

same issue arrived , i solved it by keeping the annotations intact and in dispatcher servlet :: keeping the base package scan as com.*. this worked for me.

I had this happen because I added an autowired dependency to my service class but forgot to add it to the injected mocks in my service unit test.

The unit test exception appeared to report a problem in the service class when the problem was actually in the unit test. In retrospect, the error message told me exactly what the problem was.

Instead of @Autowire MailManager mailManager, you can mock the bean as given below:

import org.springframework.boot.test.mock.mockito.MockBean;


::
::


@MockBean MailManager mailManager;

Also, you can configure @MockBean MailManager mailManager; separately in the @SpringBootConfiguration class and initialize like below:

@Autowire MailManager mailManager

I was facing the same issue while auto-wiring the class from one of my jar file. I fixed the issue by using @Lazy annotation:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;


@Autowired
@Lazy
private IGalaxyCommand iGalaxyCommand;


Faced the same issue in my spring boot application even though I had my package specific scans enabled like

@SpringBootApplication(scanBasePackages={"com.*"})

But, the issue was resolved by providing @ComponentScan({"com.*"}) in my Application class.

The solution that worked for me was to add all the relevant classes to the @ContextConfiguration annotation for the testing class.

The class to test, MyClass.java, had two autowired components: AutowireA and AutowireB. Here is my fix.

@ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class})
public class MyClassTest {
...
}

I had faced the same problem, Issue SOlved using below steps:

  1. Check the class/Interface that you are auto wiring
  2. For Interface Business logic we should use @service when it extends the Interface method.
  3. For Dao that is a Database handling class we should use @Repository.

→ We can use @Service, @Repository and @Component annotation effectively and solve this issue very fast.

if you are testing the DAO layer you must use @Autowire annotation like this:

@Autowired
private FournisseurDao fournisseurDao;

Don't inject a repository element in the constructor

I've reproduced similar issue in multi-module project w/ No qualifying bean of type like:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.stockclient.repository.StockPriceRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

and the reason for this error was missing annotation @EnableJpaRepositories in my specific use case.

To clarify: this annotation needs to be added for enabling auto configuration support for Spring Data JPA required to know the path of JPA repositories. By default, it will scan only the main application package and its sub packages for detecting the JPA repositories.

For more details you can refer, for instance, to this article.

This also happened to me when I had two methods with the same name marked @Bean in different @Configuration classes. It appears that one of the declarations was overriding the other.