问题
I have a question. I tried to run my web application using Spring and Hibernate/ I have a strange error. NoSuchBeanDefinitionException. Stacktrace is:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
I do not know why, because in my servlet-context.xml I declared SessionFacory bean:
<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"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:component-scan base-package="com.example" />
<context:component-scan base-package="com.example.service" />
<context:component-scan base-package="com.example.service.impl" />
<context:component-scan base-package="com.example.dao" />
<context:component-scan base-package="com.example.dao.impl.hibernate" />
<context:component-scan base-package="com.example.web.controller" />
<context:component-scan base-package="com.example.entity" />
<mvc:annotation-driven />
<tx:annotation-driven />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="userDAO" class="com.example.dao.impl.hibernate.HibernateUserDAO" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/userdb" />
<property name="username" value="user" />
<property name="password" value="pswd" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.example.entity.User</value>
<value>com.example.entity.Role</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Also, I annotated all DAO implementations and service implementations. Any ideas?
Added
This is part of my code:
@Repository
public class HibernateUserDAO implements UserDAO {
@Autowired
private SessionFactory sessionFactory;
...
}
And Service class:
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Autowired
private UserDAO userDAO;
@Override
@Transactional
public void create(User user) throws SQLException {
userDAO.create(user);
}
full stacktrace:
Sep 20, 2013 10:54:10 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class
org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateUserDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.example.dao.impl.hibernate.HibernateUserDAO.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] 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), @org.springframework.beans.factory.annotation.Qualifier(value=sessionFactory)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.example.dao.impl.hibernate.HibernateUserDAO.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] 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), @org.springframework.beans.factory.annotation.Qualifier(value=sessionFactory)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 23 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] 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), @org.springframework.beans.factory.annotation.Qualifier(value=sessionFactory)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 25 more
This is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/root-context.xml
/WEB-INF/application-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
回答1:
I would start with cleaning your configuration
This
<context:component-scan base-package="com.example" />
Includes all this
<context:component-scan base-package="com.example" />
<context:component-scan base-package="com.example.service" />
<context:component-scan base-package="com.example.service.impl" />
<context:component-scan base-package="com.example.dao" />
<context:component-scan base-package="com.example.dao.impl.hibernate" />
<context:component-scan base-package="com.example.web.controller" />
<context:component-scan base-package="com.example.entity" />
You are using component scanning so no need to explicitly define all the beans (it would make component scanning pretty useless if that was still needed).
Next these 2 beans
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
Are already implied by <mvc:annotation-driven />
Basically leaves you with this
<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"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:component-scan base-package="com.example" />
<mvc:annotation-driven />
<tx:annotation-driven />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/userdb" />
<property name="username" value="user" />
<property name="password" value="pswd" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.example.entity.User</value>
<value>com.example.entity.Role</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Not that it will solve your problem because the error is not due to the fact that the configuration is incomplete, but the configuration is in the wrong place. The datasource
, sessionFactory
, transactionManager
and <tx:annotation-driven .. />
must be moved to the applicationContext.xml
. Nex to that your applicationContext.xml should also include a component-scan which scans for everything but controllers.
<context:component-scan base-package="com.example">
<context:exclude-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan">
Change the <component-scan .. />
in your servlet-context.xml to
<context:component-scan base-package="com.example" use-default-filters="false">
<context:include-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan">
This to prevent duplicate instantiation of your @Service
and @Repository
beans. Which is what is happening now (both your ContextLoaderListener
and DispatcherServlet
are loading and creating the same beans, which would lead you to other nice exceptions and next to that duplication of memory as you have 2 instances of each bean in memory).
回答2:
Somtimes what Spring actually trying to say is:
There are multiple bean definitions...
I had this problem:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'metadataGeneratorFilter' is defined
once where I had an xml file like this:
<security:custom-filter ref="metadataGeneratorFilter" before="CHANNEL_FILTER"/>
<beans:bean id="metadataGeneratorFilter"
class="org.springframework.security.saml.metadata. MetadataGeneratorFilter">
<beans:constructor-arg ref="metadataGenerator"/>
</beans:bean>
回答3:
If you use @Autowired you don't need to declare like a property at the context. But it must be at the context--->NoSuchBeanDefinition--> don't find it.
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<property name="userDAO" ref="userDAO" />
</bean>
try to remove userDAO from property context.--if you autowired it, you don't need it at context.
but the problem seems to be at this bean:
<bean id="userDAO" class="com.example.dao.impl.hibernate.HibernateUserDAO" />
can't inject the dependency of sessionFactory, but everything seems to be correct :( why don't you try to remove @autowired of session factory, put get/set an add property ref at context in hibernateUserDao, just for testing what happens?
来源:https://stackoverflow.com/questions/18911356/nosuchbeandefinitionexception-how-to-initialise-sessionfactory-bean