简体   繁体   English

无法在春季自动装配sessionfactory bean

[英]unable to autowire sessionfactory bean in spring

I have searched for various solutions but nothing helping me. 我已经搜索了各种解决方案,但没有任何帮助。

ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.oodles.app.dao.impl.RoleDAOImpl.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)}

web.xml web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Loads Spring Security config file -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/spring-security.xml</param-value>
    </context-param>

    <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>
    <!-- spring security config ends here -->

</web-app>

servlet-context.xml servlet的context.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:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

  <!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with 
       username root and blank password. Change below if it's not the case -->
  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!--
     <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost:5432/testdb"/>
    <property name="username" value="postgres"/>
    <property name="password" value="postgres"/>
    <property name="validationQuery" value="SELECT 1"/> 
    -->

     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/testdb"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
    <property name="validationQuery" value="SELECT 1"/> 

  </bean>

  <!-- Hibernate Session Factory -->
  <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="packagesToScan">
      <array>
        <value>com.oodles.app.domain</value>
      </array>
    </property>
    <property name="hibernateProperties">
      <value>hibernate.dialect=org.hibernate.dialect.MySQLDialect</value>
      <value>hibernate.show_sql=true</value>
    </property>
  </bean>

  <!-- Hibernate Transaction Manager -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>

  <!-- Activates annotation based transaction management -->
  <tx:annotation-driven transaction-manager="transactionManager"/>

  <!-- Enable @Controller annotation support -->
  <mvc:annotation-driven />

  <!-- Map simple view name such as "test" into /WEB-INF/test.jsp -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
  </bean>

  <mvc:resources mapping="/resources/**" location="/resources/" />

  <!-- Scan classpath for annotations (eg: @Service, @Repository etc) -->
  <context:component-scan base-package="com.oodles.app.aspectj , com.oodles.app.domain, 
                                com.oodles.app.dao, com.oodles.app.controller, 
                                com.oodles.app.services, com.oodles.app.dao.impl,
                                com.oodles.app.services.impl" />

   <aop:aspectj-autoproxy />

</beans>

spring-security.xml 弹簧security.xml文件

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <mvc:annotation-driven />
    <context:component-scan base-package="com.oodles.app.aspectj , com.oodles.app.domain, 
                                com.oodles.app.dao, com.oodles.app.controller, 
                                com.oodles.app.services, com.oodles.app.dao.impl,
                                com.oodles.app.services.impl" />

    <http auto-config='true'>
        <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/**" access="ROLE_ADMIN" />
        <form-login 
            login-page='/login' 
            default-target-url="/" 
            authentication-failure-url="/login?error" 
            username-parameter="j_username"
            password-parameter="j_password" />
      </http>

    <!-- <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
                <user name="bob" password="bobspassword" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager> -->


    <authentication-manager>  
        <authentication-provider user-service-ref="customUserDetailsService">  
            <password-encoder hash="plaintext">  
        </password-encoder></authentication-provider>  
    </authentication-manager> 

</beans:beans>

RoleDAO.java RoleDAO.java

package com.oodles.app.dao;

import com.oodles.app.domain.Role;

public interface RoleDAO
{
    public Role getRole(int id);
}

RoleDAOImpl.java RoleDAOImpl.java

package com.oodles.app.dao.impl;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.oodles.app.dao.RoleDAO;
import com.oodles.app.domain.Role;

@Repository(value="roleDao")
public class RoleDAOImpl implements RoleDAO {

    @Autowired
    private SessionFactory sessionFactory;

    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public Role getRole(int id) {
        Role role = (Role) getCurrentSession().load(Role.class, id);
        return role;
    }
}

I also tried with adding @Qualifier("sessionFactory") with @Autowired in RoleDAOImpl. 我还尝试过在RoleDAOImpl中使用@Autowired添加@Qualifier(“ sessionFactory”)。 But it didnt worked. 但是它没有用。

Please help. 请帮忙。

The problem lies in the way you are bootstraping Spring in the Servlet container. 问题在于您在Servlet容器中引导Spring的方式。

In web.xml you are creating a root application context out of spring-security.xml and also a web application context out of servlet-context.xml . 在web.xml中,您将根据spring-security.xml创建一个根应用程序上下文,并根据servlet-context.xml创建一个Web应用程序上下文。

The issue is that beans present in the web application context are not visible to beans in the root application context. 问题是Web应用程序上下文中存在的bean对根应用程序上下文中的bean不可见。

There are multiple solutions to the problem you have, one of which would be to move your Database related configuration into the root application context. 您有多种解决方案,其中一种是将与数据库相关的配置移到根应用程序上下文中。 Your web.xml would look like this: 您的web.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
       <servlet-name>appServlet</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Loads Root application context -->
    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/spring/appServlet/applicationContext.xml</param-value>
    </context-param>

    <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>
    <!-- spring security config ends here -->

</web-app>

I have renamed spring-security.xml to applicationContext.xml and it contains the code that your spring-security.xml contained plus the extra following code (that is moved from servlet-context.xml ): 我已经将spring-security.xml重命名为applicationContext.xml ,它包含了spring-security.xml包含的代码以及以下额外的代码(从servlet-context.xml移出):

<!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with 
       username root and blank password. Change below if it's not the case -->
  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!--
     <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost:5432/testdb"/>
    <property name="username" value="postgres"/>
    <property name="password" value="postgres"/>
    <property name="validationQuery" value="SELECT 1"/> 
    -->

     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/testdb"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
    <property name="validationQuery" value="SELECT 1"/> 

  </bean>

  <!-- Hibernate Session Factory -->
  <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="packagesToScan">
      <array>
        <value>com.oodles.app.domain</value>
      </array>
    </property>
    <property name="hibernateProperties">
      <value>hibernate.dialect=org.hibernate.dialect.MySQLDialect</value>
      <value>hibernate.show_sql=true</value>
    </property>
  </bean>

  <!-- Hibernate Transaction Manager -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>

  <!-- Activates annotation based transaction management -->
  <tx:annotation-driven transaction-manager="transactionManager"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM