27
votes

I keep getting this error, and can't figure out why.. yes I know there many people had similar issues, but reading the answers they got, does not solve my problem.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.service.ContactService net.controller.ContactController.contactService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [net.service.ContactService] 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)}

here is the controller:

@Controller
@SessionAttributes
public class ContactController {

    @Autowired
    private ContactService contactService;
//methods...


}

the ContactServiceImpl

@Service("contactService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ContactServiceImpl implements ContactService {

    @Autowired
    private ContactDao contactDao;

    public ContactServiceImpl() {
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public void addContact(Contact contact) {
        contactDao.saveContact(contact);
    }

    @Override
    public List<Contact> getContacts() {
        return contactDao.getAllContacts();
    }

}

the ContactDaoImpl

@Repository("contactDao")
public class ContactDaoImpl implements ContactDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void saveContact(Contact contact) {
        sessionFactory.getCurrentSession().saveOrUpdate(contact);
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Contact> getAllContacts() {
        return (List<Contact>) sessionFactory.getCurrentSession().createQuery("from contact c").list();
    }

}

and the spring-servlet.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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:property-placeholder location="classpath:jdbc.properties" />
    <context:component-scan base-package="net.controller" />


    <tx:annotation-driven transaction-manager="hibernateTransactionManager" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>net.form.Contact</value>
            </list>
        </property>


        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>
7
so do you have setter method for contactService field?sundar
@sundar you don't need a setter method for that field in order for Spring injection to work. At any rate, the problem here is clearly the fact that the bean to inject is not found as far as Spring knows, not that it's found but it is unable to inject it.Shivan Dragon
@DaveNewton: doh, you're right, I wrote a fancy long answer that doesn't mention that at all. Yes, if the package containing ContactServiceImpl is not amongs those declared as annotation-scannable, the bean will not be created and hence not be available for injection in other beansShivan Dragon
<context:component-scan base-package="net" /> solved the problem as Pyranja suggested belowSanyifejű
@pr123 And as I suggested in my comment prior to that.Dave Newton

7 Answers

35
votes

In spring servlet .xml :

<context:component-scan base-package="net.controller" />

(I assumed that the service impl is in the same package as the service interface "net.service")

I think you have to add the package net.service (or all of net) to the component scan. Currently spring only searches in net.controller for components and as your service impl is in net.service, it will not be instantiated by spring.

11
votes

I was getting this same error and searching for it led me here. My fix appeared to be simply to add @Component annotation to the implementation of the abstract service.

In this case, that would look like:

import org.springframework.stereotype.Component;

...

@Component
public class ContactServiceImpl implements ContactService {
9
votes

Well there's a problem with the creation of the ContactServiceImpl bean. First, make sure that the class is actually instantiated by debugging the no-args constructor when the Spring context is initiated and when an instance of ContactController is created.

If the ContactServiceImpl is actually instantiated by the Spring context, but it's simply not matched against your @Autowire annotation, try being more explicit in your annotation injection. Here's a guy dealing with a similar problem as yours and giving some possible solutions:

http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

If you ask me, I think you'll be ok if you replace

@Autowired
private ContactService contactService;

with:

@Resource
@Qualifier("contactService")
private ContactService contactService;
6
votes

When you get this error some annotation is missing. I was missing @service annotation on service. When I added that annotation it worked fine for me.

1
votes

I've faced the same issue today. Turned out to be I forgot to mention @Service/@Component annotation for my service implementation file, for which spring is not able autowire and failing to create the bean.

0
votes

I had exactly the same problem try to put the two classes in the same package and add line in the pom.xml

<dependency> 
            <groupId> org.springframework.boot </groupId> 
            <artifactId> spring-boot-starter-web </artifactId> 
            <version> 1.2.0.RELEASE </version> 
</dependency>
0
votes

In java config,make sure you have import your config in RootConfig like this @Import(PersistenceJPAConfig.class)