Frühjahr Autowiring-Service funktioniert nicht in meinem Controller
habe ich Probleme, um autowire einen Dienst in meinem controller. Ich habe diesen Fehler:
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)}
Scheint es, dass der userService ist nicht registriert, so dass der controller nicht die Bohne. Ich dachte, dass meine config war ok, denn es funktioniert mit den tests. In den tests habe ich dieses:
ClassPathXmlApplicationContext("/WEB-INF/app-config.xml");
und ich kann die Bohnen ok aus ApplicationContext.xml
Mein Paket-Struktur ist die folgende:
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
.....
Den 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<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.springframework.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
Habe ich überprüft, einige Fragen zu diesem Thema, aber ich finde nicht die Lösung zu meinem problem. Vielleicht habe ich überspringe etwas, aber ich weiß nicht, sicherlich. Ich habe versucht, ändern Sie die Komponente-scan mit keine Ergebnisse.
Wenn ich versuche, Zugriff auf /SPRING-MVC/getUsers.gehen scheint, diese Fehler.
Ich weiß nicht, ob die Bohnen gelegt werden muss, in app-config (Datei ApplicationContext) oder in der servlet.xml da ist es ein bisschen verwirrend...
Danke
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Konfiguration ist sehr seltsam...
Erste Regel die offensichtliche
Sehe ich nicht root-web-Anwendung, die Kontext-Konfiguration in Ihrer
web.xml
. Könnte es sein, dass Sie vergessen haben, fügen Sie dieses Stück code?Jetzt ein wenig Theorie
Bisschen Theorie Frühling - Frühling verwendet die Anwendung, die Kontext-Hierarchie für die web-Anwendungen:
ContextLoaderListener
DispatcherServlet
InstanzenWenn eine neue bean instanziiert wird, kann es Abhängigkeiten entweder aus dem Kontext, in dem es definiert wird oder aus übergeordneten Kontext. Dies macht es möglich, zu definieren, gemeinsame Bohnen in den root-Kontext ("services, DAO, ...) und haben die request-Verarbeitung beans im servlet-Anwendung zusammenhängen, da jedes servlet kann einen eigenen Satz von Reglern, anzeigen, Linkshänder, ...
Last, but not least - Ihre Fehler
Den Sie konfigurieren MVC in Ihrem root-Kontext. Das ist einfach falsch. Entfernen Sie die
<mvc:
Kontext von dort.Sind Sie auch bei der Registrierung können Sie Ihre Steuerungen im root-Kontext über die
<context:component-scan>
auf Ihre Basis-Paket. Damit die Komponente scan nur auf dieservices
Paket oder separate Klassen in zwei top-level-Paketecore
(für die root-Bohnen) und -servlet
(für servlet-Bohnen).ContextLoaderListener
in Ihremweb.xml
(oder verwenden SieWebappInitializer
).Stellen Sie sicher, dass Ihre
UserServiceImpl
ist in der gleichen Verpackung, wie definiert incontext:component-scan
. Wenn nicht, wird der Frühling nicht in der Lage sein, es zu erkennen. Versuchen Sie auch, das entfernen von value-Attribut vonUserServiceImpl
definition, da es nur 1 Bohne in der Art. Der Frühling wird in der Lage sein, um autowire es durch Art.Müssen Sie ändern die Weise, die Sie haben autowired der service in den controller.
Ändern Sie den folgenden code
mit folgenden
Weil in der UserServiceImpl Sie haben die @Service-annotation mit dem alias "userService".
Ich hoffe, das würde das problem beheben. 🙂
wenn Sie jemals konfrontiert diese Art von problem, bitte prüfen, was ist der Pfad zum context:component-scan basepackage
sollte es werden root-name-Gefällt, wenn ich die com.mike als Paket-name & enthalten bean,controller,dao,service-Ordner in der Struktur, dann, in solchen Bedingung, die Sie haben zu Folgen Wie ----context:component-scan basepackaage="com.mike.*"
wobei * bedeutet, dass alle Ordner (Bohnen -, service -, dao -, controller-und theieanwendung entsprechenden Klassen) werden scaned.
Können Sie die
@Qualifier
annotation wie folgt:Auf den ersten Blick die config scheint ok, aber es kann einige kleinere tripwires, die möglicherweise nicht so offensichtlich sind.
a) umgesetzt
UserService
interface, ist es der gleiche wie der controller braucht? Dumme Frage, ich weiß, aber nur auf der sicheren Seite.b) bean-name: Versuchen Sie, die Beseitigung der
value
-Wert (ba-da-tush) aus der@Service
annotation, seine sowieso überflüssig wurde. Oder genauer mit Hilfe eines@Qualifier
.c) Paket-scan: Doppelklicken Sie überprüfen, ob Ihr service implementiert ist wirklich innerhalb
es.unican.meteo
. Manchmal ist es die kleinen Dinge.@Service
sollte ausreichen, oder wo Sie@Autowired
man könnte hinzufügen@Qualifier("userService")
weiter spezifizieren die Bohne, wenn autowire von Namen nicht anders. C: Klingt gut dann