使用 Spring 和 Spring Security 正确注入 SessionFactory

Posted

技术标签:

【中文标题】使用 Spring 和 Spring Security 正确注入 SessionFactory【英文标题】:Proper injection of SessionFactory with Spring and Spring Security 【发布时间】:2011-07-14 11:56:16 【问题描述】:

我有这个例外

java.lang.NullPointerException
cz.xkadle21.dip.dao.ADiHibernateGenericDAO.findByCriteria(ADiHibernateGenericDAO.java:116)
cz.xkadle21.dip.dao.impl.DiUserDAO.findUserByUsername(DiUserDAO.java:86)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:47)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:1)

我正在关注本教程Spring Security 3 database authentication with Hibernate

并得到“未定义名为 ... 的 bean”错误。所以我将 bean 从 dispatcher-servlet.xml 移动到 applicationContext-common-business.xml 并更改 web.xml 中的加载

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext-common-business.xml 
        /WEB-INF/applicationContext-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>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

despatcher-servlet.xml 中的 Bean 正在加载组件扫描,并且正在自动且正确地注入 sessionFactory。但是 applicationContext-common-business.xml 中的 bean 没有。

applicationContext-common-business.xml

<bean name="userDetailsService"
    class="cz.xkadle21.dip.service.impl.DiUserContextSecurityService" >
     <constructor-arg ref="userDAO" /> 
     <constructor-arg ref="securityUserFactory" />      
</bean>

<bean id="securityUserFactory" class="cz.xkadle21.dip.factory.impl.DiSecurityUserFactory" />
<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO" />



<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="/WEB-INF/jdbc.properties" />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="$hibernate.connection.driver_class"
    p:url="$hibernate.connection.url" p:username="$hibernate.connection.username"
    p:password="$hibernate.connection.password" />


<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>


    <property name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
        </props>
    </property>
</bean>

UserDetailsS​​ervice 是通过构造函数注入的,但是如何将 sessionFactory 注入到 userDAO 中呢? SessionFactory在ADiHibernateGenericDAO中定义,所有DAO都扩展了抽象的ADiHibernateGenericDAO。上面的异常是在SessionFactory上抛出的,没有注入。

感谢您的回复。

【问题讨论】:

【参考方案1】:

伙计,我没有看到任何事务管理器或

写在你的 bean 配置文件的任何地方。如果你还没有,你应该把它放在那里。这可能是问题所在。

【讨论】:

嗨,我已经想通了。我认为这个定义应该只在一个配置文件中。所以我把它放在两者上,现在它可以正常工作了。 放入-servlet.xml 好吧,当它仅在 -servlet.xml 中时,bean 中的事务不工作,通过 applicationContext-common-business.xml 配置文件加载【参考方案2】:

您尚未向我们展示您的 DiUserDAO 类,但假设您有一个用于 setSessionFactory() 的设置器,您可以简单地将您的 XML 映射更改为:

<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

或者,您可以修改 DiUserDAO 类以将 SessionFactory 字段标记为 @Autowired

相同的解决方案适用于需要访问此 bean 的任何其他 bean。

【讨论】:

是的,你说得对。我在直接注入抽象类之前尝试过。使用注释它对我不起作用。仅通过构造函数或设置器(我在想,注释仅在 dispatcher-servlet.xml 配置中起作用。)现在我有“没有绑定到线程的 Hibernate Session”,但也许这可以自行解决。再次感谢您的回复

以上是关于使用 Spring 和 Spring Security 正确注入 SessionFactory的主要内容,如果未能解决你的问题,请参考以下文章

Spring security @secure 不适用于角色层次结构

Grails Spring Core 安全插件 - 无法解析类

Spring Security应用开发(20)基于方法的授权使用@RolesAllowed注解

BCryptPasswordEncoder 未作为 spring-boot-starter-security 的一部分导入

容器化 Spring Boot 应用程序时出现 Docker 错误

Spring Security OAuth - 访问此资源需要完全身份验证