Spring Autowiring service not working in my controller

I am having trouble auto-installing a service in my controller. I have this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [es.unican.meteo.service.UserService] 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)} 

It seems that userService is not registered, so the controller cannot get a bean. I thought my configuration was ok because it works with tests. In tests, I have the following:

 ClassPathXmlApplicationContext("/WEB-INF/app-config.xml"); 

and I can get bean ok from ApplicationContext.xml

My package structure is as follows:

es.unican.meteo.controller

| ---- MyController.java

es.unican.meteo.service

| ---- UserService.java

es.unican.meteo.service.impl

| ---- UserServiceImpl.java

.....

WebContent / WEB-INF

| ---- MyDispatcherServlet-servlet.xml

| ---- app-config.xml

| ---- web.xml

.....

Classes:

== UserServiceImpl.java ==

 @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; public void setUserMapper(UserMapper userMapper) { this.userMapper = userMapper; } 

== MyController.java ==

 @Controller public class MyController { @Autowired private UserService userService; @RequestMapping(method=RequestMethod.GET, value="/home") public String handleRequest(){ return "welcome"; } @RequestMapping(method=RequestMethod.GET, value="/getUsers") public @ResponseBody List<User> getUsersInJSON(){ return userService.getUsers(); } } 

== web.xml ==

 <display-name>Spring MVC</display-name> <servlet> <servlet-name>MyDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyDispatcherServlet</servlet-name> <url-pattern>*.go</url-pattern> </servlet-mapping> </web-app> 

== app-config.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:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <!-- Scans the classpath of this application for @Components to deploy as beans --> <context:component-scan base-package="es.unican.meteo" /> <!-- Configures the @Controller programming model --> <mvc:annotation-driven/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="org.apache.derby.jdbc.EmbeddedDriver" p:url="jdbc:derby:C:\tools\derbydb" p:connectionProperties="" p:username="APP" p:password="" /> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="/mybatis-config.xml" /> </bean> <bean id="usersMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="es.unican.meteo.dao.UserMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> <bean id="rolesMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="es.unican.meteo.dao.RoleMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> </beans> 

== MyDispatcherServlet.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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <!-- Enabling Spring beans auto-discovery --> <context:component-scan base-package="es.unican.meteo.controller" /> <!-- Enabling Spring MVC configuration through annotations --> <mvc:annotation-driven /> <!-- Defining which view resolver to use --> <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> 

Spring mvc logger trace:

 19:38:54,119 DEBUG http-8080-1 support.DefaultListableBeanFactory:430 - Creating instance of bean 'myController' 19:38:54,170 DEBUG http-8080-1 annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.controller.MyController]: AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService 19:38:54,174 DEBUG http-8080-1 support.DefaultListableBeanFactory:504 - Eagerly caching bean 'myController' to allow for resolving potential circular references 19:38:54,206 DEBUG http-8080-1 annotation.InjectionMetadata:85 - Processing injected method of bean 'myController': AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService 19:38:54,224 DEBUG http-8080-1 support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'userServiceImpl' 19:38:54,226 DEBUG http-8080-1 support.DefaultListableBeanFactory:430 - Creating instance of bean 'userServiceImpl' 19:38:54,234 DEBUG http-8080-1 annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.service.impl.UserServiceImpl]: AutowiredFieldElement for private es.unican.meteo.dao.UserMapper es.unican.meteo.service.impl.UserServiceImpl.userMapper 19:38:54,237 DEBUG http-8080-1 support.DefaultListableBeanFactory:504 - Eagerly caching bean 'userServiceImpl' to allow for resolving potential circular references 19:38:54,256 DEBUG http-8080-1 annotation.InjectionMetadata:85 - Processing injected method of bean 'userServiceImpl': AutowiredFieldElement for private es.unican.meteo.dao.UserMapper es.unican.meteo.service.impl.UserServiceImpl.userMapper 19:38:54,268 INFO http-8080-1 support.DefaultListableBeanFactory:433 - Destroying singletons in org.s pringframework.beans.factory.support.DefaultListableBeanFactory@ 56088b29: defining beans [myController,roleService,userServiceImpl,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.view.InternalResourceViewResolver#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy 19:38:54,279 ERROR http-8080-1 servlet.DispatcherServlet:457 - Context initialization failed 

I examined some questions on this topic, but I did not find a solution to my problem. Maybe I'm missing something, but I don’t know, of course. I tried changing the component scan without any results.

When I try to access / SPRING-MVC / getUsers.go, these errors will appear.

I don't know if the beans should be hosted in app-config (applicationContext) or in servlet.xml because it is a bit confusing ...

thanks

+8
source share
7 answers

Your configuration is very strange ...

Rule out the obvious first

I do not see the context configuration of the root web application in web.xml . Maybe you forgot to add this piece of code?

 <context-param> <param-name>contextConfigLocation</param-name> <param-value> WEB-INF/app-config.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 

Now a little theory

Spring theory bit - Spring uses the application context hierarchy for web applications:

  • top-level web application context loaded by ContextLoaderListener
  • then for each instance of DispatcherServlet there are separate contexts

When a new bean is created, it can receive dependencies either from the context where it is defined or from the parent context. This allows you to determine the common beans in the root context (services, DAO, ...) and process the beans request in the context of servlet applications, since each servlet can have its own set of controllers, a viewer, ...

Last but not least, your mistakes

You configure MVC in the root context. This is simply wrong. Remove the <mvc: context.

You also register your controllers in the root context via <context:component-scan> in the base package. Do component checking only in the services package or split your classes into two top-level packages core (for root beans) and servlet (for beans servlet).

+11
source

Make sure your UserServiceImpl is in the same package as in context:component-scan . If this is not the case, spring will not be able to detect it. Also try removing the value attribute from the UserServiceImpl definition, as there is only 1 bean of this type. spring will be able to auto-install it by type.

+5
source

You need to change the way the service connects automatically in the controller.

Change the following code

 @Autowired private UserService userService; 

with the following

 @Resource(name="userService") private UserService userService; 

Because in UserServiceImpl, you defined the @Service annotation with the alias "userService".

Hope this solves your problem. :)

+1
source

when you encounter such a problem, kindly check what the path for the context is: basepackage component-scan

it must be the root name. As if I took com.mike as the name of the package and which contains the bean, controller, dao, service folder in my structure, then in this state you should follow Like ---- context: scanning component basepackaage = "com.mike . * "

where * means that the entire folder will be scanned (bean, service, dao, controller and corresponding classes).

+1
source

You can use the @Qualifier annotation as follows:

 @Autowired @Qualifier("userService") private UserService userService; 
0
source

At first glance, the configuration looks fine, but there may be some smaller triplets that may not be so obvious.

a) the implemented UserService interface, is it the same as the controller needs? Stupid question, I know, but just being safe.

b) bean name: try to root out value -value (ba-da-tush) from the @Service annotation, in any case, its superdense. Or more specifically with @Qualifier .

c) packet scanning: double check if your deployed service is really within es.unican.meteo . Sometimes these are trifles.

0
source

Add the @Component annotation to your service. Should work fine

0
source

All Articles