首页 > 解决方案 > Spring Security 问题创建 bean

问题描述

使用 Spring Security,我正在尝试使用 Spring 创建以下身份验证验证。

@Service("LoginUserDetailsServiceImpl")
public class LoginUserDetailsServiceImpl implements UserDetailsService  {

    private static final Logger logger = Logger.getLogger(UserDetailsService.class);

    @Autowired
    private CustomerDao customerDao;

    @Override
    public UserDetails loadUserByUsername(String  email) throws UsernameNotFoundException {
        logger.info("Customer DAO Email:" +email);
        Customer customer = customerDao.getCustomer(email);
        logger.info("Customer DAO Email:" +customer.getEmail());        
        Roles role = customer.getRole();
        logger.info("Customer DAO Role:" + role.getRoles());
        MyUserPrincipalimpl principal = new MyUserPrincipalimpl(customer);


        logger.info("customerUserDetails DAO:" +principal);
           if (customer == null) {
                throw new UsernameNotFoundException(email);
            }


           return principal;
        }

}

这会产生以下错误

5:56,638  WARN XmlWebApplicationContext:487 - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'LoginUserDetailsServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emusicstore.dao.CustomerDao com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emusicstore.dao.CustomerDao] 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.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)

我发现如果我注释掉以下内容

<bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>

从我的 application-security.xml 不会产生上述错误。我的junit测试也将毫无问题地执行。

@Autowired
    CustomerDao customerDao;

    @Test
    public void LoginService() {
        String email="customeremail";
        logger.info("Customer DAO Email:" +email);
        Customer customer = customerDao.getCustomer(email);
        logger.info("Customer DAO Email:" +customer.getEmail());        
        Roles role = customer.getRole();
        logger.info("Customer DAO Role:" + role.getRoles());

    }

回购

@Repository

    public class CustomerDaoImp implements CustomerDao {

        private static final Logger logger = Logger.getLogger(CustomerDaoImp.class);

        @Autowired
        SessionFactory sessionFactory;

应用程序-security.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:security="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:webflow-config="http://www.springframework.org/schema/webflow-config"
    xsi:schemaLocation=" http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/security 
       http://www.springframework.org/schema/security/spring-security.xsd 
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/security 
       http://www.springframework.org/schema/security/spring-security.xsd 
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">


<!-- <bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>-->

    <security:http auto-config="true"  use-expressions="true">
        <security:intercept-url pattern="/login_test" access="permitAll" />
        <security:intercept-url pattern="/logout" access="permitAll" />
        <security:intercept-url pattern="/accessdenied" access="permitAll" />
        <security:intercept-url pattern="/productList" access="permitAll" />
<!--         <security:intercept-url pattern="/**" access="permitAll" /> -->
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
        <security:intercept-url pattern="/shoppingCart/checkOut" access="hasRole('ROLE_USER')" />
        <security:form-login login-page="/login_test" login-processing-url="/j_spring_security_check" authentication-failure-url="/accessdenied" 
        />
        <security:logout logout-success-url="/logout" />
    </security:http> 


 <!--  <security:authentication-manager>-
        <security:authentication-provider user-service-ref="LoginUserDetailsServiceImpl"/>
    </security:authentication-manager> -->

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:user-service>
                <security:user name="lokesh" password="password" authorities="ROLE_USER" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>


    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"
            value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/mydb" />
        <property name="username" value="root" />
        <property name="password" value="t3l3com" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.emusicstore</value>
            </list>
        </property>
    </bean>


    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="1024000" />
    </bean>

</beans>

Spring-servlet.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"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">



    <mvc:annotation-driven></mvc:annotation-driven>

    <context:component-scan base-package="com.emusicstore"></context:component-scan>


    <bean id="viewresolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>

    </bean>

    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

        <!-- setting maximum upload size -->
        <property name="maxUploadSize" value="10000000" />

    </bean>

    <mvc:resources location="/WEB-INF/resource/" mapping="/resource/**"></mvc:resources>

     <tx:annotation-driven />


</beans>

我不确定问题到底出在哪里,但我猜它是如何在 xml 中配置 bean 的。我应该在我的 xml 文件中引用 customerDao bean 吗?我会认为@Autowired 注释会解决这个问题?

更新 如果我更新应用程序安全性以添加新的 Customer Dao bean,则会引发新的错误消息。

<bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>
<bean id="CustomerDao" class="com.emusicstore.daoImpl.CustomerDaoImp"/> 

我收到以下错误'org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.emusicstore.dao.CustomerDao] is defined: expected single matching bean but found 2: customerDaoImp,CustomerDao'

标签: javaspringspring-security

解决方案


The problem is a CustomerDao instance can't be found by Spring. Either it's failed to instantiate somewhere higher up in your logs, or likely it hasn't been defined in a way that it can be instantiated and made available for injection by Spring Framework.

If you're using XML based dependency injection then defined CustomerDao instance with id customerDao in your XML similar to how LoginUserDetailsServiceImpl is defined.

Or if you're using annotation based dependency injection then add the appropriate stereotype annotation (@Component, @Repository etc) to the CustomerDao so Spring IoC knows to instantiate it and make is available for dependency injection.


推荐阅读