Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Autowired - No qualifying bean of type found for dependency

I've started my project by creating entities, services and JUnit tests for services using Spring and Hibernate. All of this works great. Then I've added spring-mvc to make this web application using many different step-by-step tutorials, but when I'm trying to make Controller with @Autowired annotation, I'm getting errors from Glassfish during deployment. I guess that for some reason Spring doesn't see my services, but after many attempts I still can't handle it.

Tests for services with

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

and

@Autowired MailManager mailManager; 

works properly.

Controllers without @Autowired too, I can open my project in web browser without trouble.

/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-dispatcher-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 <[email protected]>  */ public class AbstractManager {      @Autowired     protected SessionFactory sessionFactory;      protected final Logger logger = Logger.getLogger(this.getClass());  } 

pl.com.radzikowski.webmail.service.MailManager

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";     }  } 

Error:

SEVERE: Exception while loading the app
SEVERE: Undeployment failed for context /WebMail
SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] 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)}

Sorry for a lot of code, but I don't know what can cause that error anymore.

Added

I've created the interface:

@Component public interface IMailManager { 

added implements:

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

and changed autowired:

@Autowired public IMailManager mailManager; 

But it still throws errors (also when I've tried with @Qualifier)

..Could not autowire field: public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager...

I've tried with different combinations of @Component and @Transactional too.

Shouldn't I include beans.xml in web.xml somehow?

like image 870
Radzikowski Avatar asked Dec 02 '13 16:12

Radzikowski


People also ask

How do I fix no qualifying bean of type?

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 @Component. The exception “NoSuchBeanDefinitionException: No qualifying bean of type” is resolved if the annotation @Component is added in the Lion class.

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 exclude a bean from being available for Autowiring?

If you are using Spring XML configuration then you can exclude a bean from autowiring by setting the autowire-candidate attribute of the <bean/> element to false. That way container makes that specific bean definition unavailable to the autowiring infrastructure.

Why Autowired is not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.


1 Answers

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.

like image 94
Patison Avatar answered Sep 22 '22 08:09

Patison