NoSuchBeanDefinitionException 如何初始化 SessionFactory bean?
Posted
技术标签:
【中文标题】NoSuchBeanDefinitionException 如何初始化 SessionFactory bean?【英文标题】:NoSuchBeanDefinitionException How to initialise SessionFactory bean? 【发布时间】:2013-09-25 12:32:03 【问题描述】:我有一个问题。我尝试使用 Spring 和 Hibernate 运行我的 Web 应用程序/我有一个奇怪的错误。 NoSuchBeanDefinitionException。堆栈跟踪是:
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)
我不知道为什么,因为在我的 servlet-context.xml 中我声明了 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>
另外,我注释了所有 DAO 实现和服务实现。 有什么想法吗?
已添加
这是我的代码的一部分:
@Repository
public class HibernateUserDAO implements UserDAO
@Autowired
private SessionFactory sessionFactory;
...
和服务类:
@Service
public class UserServiceImpl implements UserService, UserDetailsService
@Autowired
private UserDAO userDAO;
@Override
@Transactional
public void create(User user) throws SQLException
userDAO.create(user);
完整的堆栈跟踪:
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
这是我的 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>
【问题讨论】:
不要让 Hibernate 在你的类路径上。确保 Hibernate 及其所有依赖项都在您的lib
文件夹中。
我确定我的类路径和 lib 文件夹中的所有必需的 jars
简而言之,您的 bean 位于错误的位置,旁边有很多重复项。如需更长的版本,请参阅我的答案。
【参考方案1】:
我会先清理你的配置
这个
<context:component-scan base-package="com.example" />
包括所有这些
<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" />
您正在使用组件扫描,因此无需显式定义所有 bean(如果仍然需要,它会使组件扫描变得毫无用处)。
接下来这两个豆子
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
已经被<mvc:annotation-driven />
暗示了
基本上只剩下这个
<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>
不会解决你的问题,因为报错不是因为配置不完整,而是配置放错了地方。 datasource
、sessionFactory
、transactionManager
和 <tx:annotation-driven .. />
必须移动到 applicationContext.xml
。除此之外,您的 applicationContext.xml 还应该包含一个组件扫描,它会扫描所有但控制器。
<context:component-scan base-package="com.example">
<context:exclude-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan">
将 servlet-context.xml 中的 <component-scan .. />
更改为
<context:component-scan base-package="com.example" use-default-filters="false">
<context:include-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan">
这是为了防止 @Service
和 @Repository
bean 的重复实例化。这就是现在发生的事情(您的ContextLoaderListener
和DispatcherServlet
都在加载和创建相同的bean,这将导致您出现其他不错的异常,并且在内存重复旁边,因为您在内存中有每个bean 的2 个实例) .
【讨论】:
为什么我需要 2 个 xml 文件?我看到了很多带有 1 个 xml 的示例。所以,我不明白这两个文件分别应该是什么? 从 yuo stacktrace 判断,您有一个ContextLoaderListener
(并且您正在使用 Spring Security)和一个 DispatcherServlet
。他们应该不都加载相同的xml文件。发布您的 web.xml。
您已经有多个文件,所以我看不到问题所在。基本上我提到 applicationContext.xml 你应该阅读 root-context.xml 和 servlet-context.xml == dispatcher-servlet.xml。【参考方案2】:
Spring 有时真正想说的是:
There are multiple bean definitions...
我遇到了这个问题:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'metadataGeneratorFilter' is defined
曾经我有一个这样的 xml 文件:
<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】:如果您使用@Autowired,则无需在上下文中声明为属性。但它必须在上下文--->NoSuchBeanDefinition--> 找不到它。
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
<property name="userDAO" ref="userDAO" />
</bean>
尝试从属性上下文中删除 userDAO。--如果您自动装配它,则在上下文中不需要它。
但问题似乎出在这个 bean 上:
<bean id="userDAO" class="com.example.dao.impl.hibernate.HibernateUserDAO" />
无法注入 sessionFactory 的依赖,但一切似乎都是正确的 :( 为什么不尝试删除会话工厂的@autowired,在 hibernateUserDao 的上下文中放置 get/set 一个 add 属性 ref,只是为了测试会发生什么?
【讨论】:
以上是关于NoSuchBeanDefinitionException 如何初始化 SessionFactory bean?的主要内容,如果未能解决你的问题,请参考以下文章