Спринг служба аўтаматычнага звязвання не працуе ў маім кантролеры

я маю праблемы з тым, каб autowire службы ў маім кантролеры. Я гэтую памылку:

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)}

Здаецца, што UserService не зарэгістраваная, так што кантролер не можа атрымаць боб. Я думаў, што мой конфіг быў нармальны, таму што ён працуе з тэстамі. У тэстах у мяне ёсць гэта:

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

і я магу атрымаць боб ОК ад applicationContext.xml

Мой пакет структура выглядае наступным чынам:

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

| ---- прыкладанне-config.xml

| ---- web.xml

.....

У clases:

== 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 getUsersInJSON(){
      return userService.getUsers();
     }
}

== == web.xml

Spring MVC

 
  MyDispatcherServlet org.springframework.web.servlet.DispatcherServlet 

 
  MyDispatcherServlet
  *.go
 

== Дадатак-config.xml ===

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



   <!-- Scans the classpath of this application for @Components to deploy as beans -->
   

   <!-- Configures the @Controller programming model -->
   

   

    
        
    

    
        
        
     

    
        
        
     

    
        
        
     


== MyDispatcherServlet.xml ==

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


 <!-- Enabling Spring beans auto-discovery -->
 

 <!-- Enabling Spring MVC configuration through annotations -->
 

 <!-- Defining which view resolver to use -->
  
   
   
 

Spring MVC рэгістратар трасіроўкі:

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[email protected]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

Я разгледзеў некаторыя пытанні па гэтай тэме, але я не знайсці рашэнне маёй праблемы. Можа быць, я прапушчу нешта, але я не ведаю, вядома. Я спрабаваў змяніць кампанент сканаванне без якіх-небудзь вынікаў.

Пры спробе доступу да /SPRING-MVC/getUsers.go з'яўляецца гэтыя памылкі.

Я не ведаю, калі бабы павінны быць змешчаны ў дадатак-канфігурацыі (ApplicationContext) або ў servlet.xml, таму што гэта крыху збівае з толку ...

Дзякуй

8

7 адказы

Ваша канфігурацыя вельмі дзіўна ...

Першае правіла на відавочнае

Я не бачу канфігурацыі кантэксту вэб-прыкладанні корань ў вашым web.xml . Можа быць, вы забыліся дадаць гэты кавалак кода?


    contextConfigLocation
    
        WEB-INF/app-config.xml
    



    org.springframework.web.context.ContextLoaderListener

Зараз трохі тэорыі

Крыху тэорыі Spring - Spring выкарыстоўвае кантэкст прыкладання іерархіі для вэб-прыкладанняў:

  • top level web application context is loaded by ContextLoaderListener
  • then there are separate contexts for each DispatcherServlet instances

Калі новы боб быць асобнік, ён можа атрымаць залежнасці альбо ад кантэксту, у якім яна вызначаецца або з бацькоўскага кантэксту. Гэта дае магчымасць вызначыць агульныя бабы ў каранёвым кантэксце (паслугі, DAO, ...) і ёсць запыт на апрацоўку збожжа ў кантэксце прыкладання сэрвлета, паколькі кожны сэрвлета можа мець свой уласны набор кантролераў, выгляд леўшуноў, ...

І апошняе, але не ў апошнюю чаргу - вашы памылкі

You are configuring MVC in your root context. That is just wrong. Remove the context from there.

You are also registering your controllers in the root context via the on your base package. Make the component scan just on the services package or separate your classes into two top level packages core (for the root beans) and servlet (for servlet beans).

11
дададзена
Я не разумею, што вы маеце на ўвазе, паказаўшы contextroot ў Eclipse. <�Я> Contextroot </я> (гэта значыць базавы уніфікаваны ідэнтыфікатар прыкладання сэрвлета) гэта іншая справа з <�б> кантэксту вэб-прыкладанні корань (вясна кантэйнер). Вы павінны мець ContextLoaderListener у web.xml (ці выкарыстоўвайце WebappInitializer ).
дададзена аўтар Pavel Horal, крыніца
Ці можаце вы прыняць адказ, калі гэта дапамагло вырашыць праблему? :)
дададзена аўтар Pavel Horal, крыніца
Перш за ўсё, дзякуй за ваш адказ. Пра «канфігурацыі кантэксту вэб-прыкладанні корань» я займаюся распрацоўкай праекта ў заняпадзе, так што вы можаце наладзіць contextroot як ўласцівасць праекта. з'яўляецца тое, што вы хочаце сказаць? Вы маеце на ўвазе, што я павінен замяніць у дадатак-config.xml «<�кантэкст: кампанент сканавання базавага пакета =» es.unican.meteo «/>» з "<�кантэкст: кампанент сканавання базы-пакет =" Ес. unican.meteo.service «/>», таму што я буду рэгістраваць кантролер у каранёвым (дадатак-канфігурацыі) і ў сэрвлета? Дзякуй!
дададзена аўтар mannuk, крыніца
Зараз, я вас разумею. Я ўключыў слухача ў web.xml і выдаліў усе спасылкі на MVC ў ApplicationContext. Цяпер яна працуе. дзякуй Паўлу
дададзена аўтар mannuk, крыніца
Гатова, дзякуй яшчэ раз
дададзена аўтар mannuk, крыніца

Ваша канфігурацыя вельмі дзіўна ...

Першае правіла на відавочнае

Я не бачу канфігурацыі кантэксту вэб-прыкладанні корань ў вашым web.xml . Можа быць, вы забыліся дадаць гэты кавалак кода?


    contextConfigLocation
    
        WEB-INF/app-config.xml
    



    org.springframework.web.context.ContextLoaderListener

Зараз трохі тэорыі

Крыху тэорыі Spring - Spring выкарыстоўвае кантэкст прыкладання іерархіі для вэб-прыкладанняў:

  • top level web application context is loaded by ContextLoaderListener
  • then there are separate contexts for each DispatcherServlet instances

Калі новы боб быць асобнік, ён можа атрымаць залежнасці альбо ад кантэксту, у якім яна вызначаецца або з бацькоўскага кантэксту. Гэта дае магчымасць вызначыць агульныя бабы ў каранёвым кантэксце (паслугі, DAO, ...) і ёсць запыт на апрацоўку збожжа ў кантэксце прыкладання сэрвлета, паколькі кожны сэрвлета можа мець свой уласны набор кантролераў, выгляд леўшуноў, ...

І апошняе, але не ў апошнюю чаргу - вашы памылкі

You are configuring MVC in your root context. That is just wrong. Remove the context from there.

You are also registering your controllers in the root context via the on your base package. Make the component scan just on the services package or separate your classes into two top level packages core (for the root beans) and servlet (for servlet beans).

11
дададзена
Я не разумею, што вы маеце на ўвазе, паказаўшы contextroot ў Eclipse. <�Я> Contextroot </я> (гэта значыць базавы уніфікаваны ідэнтыфікатар прыкладання сэрвлета) гэта іншая справа з <�б> кантэксту вэб-прыкладанні корань (вясна кантэйнер). Вы павінны мець ContextLoaderListener у web.xml (ці выкарыстоўвайце WebappInitializer ).
дададзена аўтар Pavel Horal, крыніца
Ці можаце вы прыняць адказ, калі гэта дапамагло вырашыць праблему? :)
дададзена аўтар Pavel Horal, крыніца
Перш за ўсё, дзякуй за ваш адказ. Пра «канфігурацыі кантэксту вэб-прыкладанні корань» я займаюся распрацоўкай праекта ў заняпадзе, так што вы можаце наладзіць contextroot як ўласцівасць праекта. з'яўляецца тое, што вы хочаце сказаць? Вы маеце на ўвазе, што я павінен замяніць у дадатак-config.xml «<�кантэкст: кампанент сканавання базавага пакета =» es.unican.meteo «/>» з "<�кантэкст: кампанент сканавання базы-пакет =" Ес. unican.meteo.service «/>», таму што я буду рэгістраваць кантролер у каранёвым (дадатак-канфігурацыі) і ў сэрвлета? Дзякуй!
дададзена аўтар mannuk, крыніца
Зараз, я вас разумею. Я ўключыў слухача ў web.xml і выдаліў усе спасылкі на MVC ў ApplicationContext. Цяпер яна працуе. дзякуй Паўлу
дададзена аўтар mannuk, крыніца
Гатова, дзякуй яшчэ раз
дададзена аўтар mannuk, крыніца

Пераканайцеся, што ваш UserServiceImpl знаходзіцца ў той жа ўпакоўцы, як вызначана ў Кантэкст: кампанент-сканавання . Калі гэта не так, увесну не будзе ў стане выявіць яго. Акрамя таго, паспрабуйце выдаліць атрыбут значэння з UserServiceImpl вызначэнне, так як існуе толькі адзін боб гэтага тыпу. Вясна будзе ў стане autowire яго тыпу.

5
дададзена
Дзякуй за гэта рашэнне, гэта выратавала мой дзень :)
дададзена аўтар 0bj3ct, крыніца

Вам трэба змяніць так, як вы autowired службы ў кантролеры.

Зменіце наступны код

@Autowired
private UserService userService;

з наступным

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

Таму што ў UserServiceImpl вы вызначылі анатацыю @Service з псеўданімам «UserService».

Я спадзяюся, што гэта дазволіць вырашыць вашу праблему. :)

1
дададзена
@SumitDesai Ды вы маеце рацыю
дададзена аўтар Japan Trivedi, крыніца
Калі ёсць толькі адзін боб гэтага тыпу, я лічу, што гэта не выкліча ніякіх праблем.
дададзена аўтар Sumit Desai, крыніца

калі-небудзь вы сутыкаецеся з такога роду праблемы, калі ласка, праверце, што шлях для кантэксту: basepackage кампанент сканавання

it should be root name Like if I am taking com.mike as package name & which contain bean,controller,dao,service folder in its structure then, in such condition you have to follow Like ----context:component-scan basepackaage="com.mike.*"

дзе * азначае, што ўсе папкі (боб, сэрвіс, дао, кантролер і theie адпаведныя класы) будуць адсканаваныя.

1
дададзена

Вы можаце выкарыстоўваць @Qualifier анатацый наступным чынам:

@Autowired
@Qualifier("userService")
private UserService userService;
0
дададзена
дзякуй за адказы, але праблема застаецца
дададзена аўтар mannuk, крыніца

На першы погляд здаецца, канфігурацыя добра, але можа быць некалькі невялікіх нацяжак, якія могуць быць не гэтак відавочная.

а) рэалізаваны UserService інтэрфейс, гэта тое ж самае, як патрэбнасці кантролера? Тупы пытанне, я ведаю, але проста быць на бяспечнай баку.

б) найменне боб: Паспрабуйце выкараненні значэнне -Value (ба-так-цьфу) з @Service анатацый, яго superflous ў любым выпадку. Або больш канкрэтна з дапамогай тэга @Qualifier .

в) сканаванне пакета: Двойчы праверце, калі ваша рэалізаваная паслуга сапраўды ў межах es.unican.meteo . Часам яго дробныя рэчы.

0
дададзена
дзякуй за ваш адказ Scorpio! а) UserServiceImpl рэалізуе UserService, які з'яўляецца служба, якая мае патрэбу ў MyController.java (UserService) б) вы хочаце сказаць, каб не ўключаць @Service (значэнне = «UserService»), толькі @Service? с) Маё сканаванне ўпакоўкі заключаецца ў наступным: <�кантэкст: кампанент сканавання базавы пакет = «es.unican.meteo» /> UserService і UserServiceImpl ў es.unican.meteo. FirstOne ў es.unican.meteo.service і secondone ў es.unican.meteo.service.impl
дададзена аўтар mannuk, крыніца
Для Ь: Так, @Service павінна быць дастаткова, ці там, дзе ў вас ёсць @Autowired можна дадаць @Qualifier ( "UserService") для больш дакладнага вызначэння боб, калі autowire па імені не можа інакш. Каб з: Гучыць добра тады
дададзена аўтар Scorpio, крыніца