Autowired Field是空的

时间:2013-08-05 15:58:10

标签: spring-mvc spring-security

我一直在研究Spring MVC + Spring Security + hibernate的一个例子来创建一个登录页面,但现在我遇到了一个燃料@Autowire的问题,它一直给我空值。服务器不会报告任何错误,只是它没有完成操作。

CustomUSerDetailsS​​ervice.java

package com.carloscortina.paidosSimple.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import com.carloscortina.paidosSimple.dao.UsuarioDao;
import com.carloscortina.paidosSimple.model.Usuario;

@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {

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

    @Autowired UsuarioDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {

        logger.info(username);
        Usuario domainUser = userDao.getUsuario(username);
        logger.info(domainUser.getUsername());

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        return new User(
            domainUser.getUsername(),
            domainUser.getPassword(),
            enabled,
            accountNonExpired,
            credentialsNonExpired,
            accountNonLocked,
            getAuthorities(domainUser.getRol().getId()));
    }

    public Collection<? extends GrantedAuthority> getAuthorities(Integer rol){
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(rol));
        return authList;
    }

    public List<String> getRoles(Integer rol){
        List<String> roles = new ArrayList<String>();

        if(rol.intValue() == 1){
            roles.add("ROLE_DOCTOR");
            roles.add("ROLE_ASISTENTE");
        }else if (rol.intValue() == 2){
            roles.add("ROLE_ASISTENTE");
        }
        return roles;
    }

    public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles){
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;

    }

}

此处字段userDao保持beign null,因此当我尝试使用userDao.getUsuario(username)时,操作只是没有继续,它不报告错误或类似情况,它只是给我一个404错误

UsuarioDao.xml

package com.carloscortina.paidosSimple.dao;

import java.util.ArrayList;
import java.util.List;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.carloscortina.paidosSimple.model.Usuario;

@Repository
public class UsuarioDaoImp implements UsuarioDao {

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

    @Autowired
    private SessionFactory sessionFactory;

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

    @Override
    public Usuario getUsuario(String username) {
        logger.debug("probando");
        List<Usuario> userList = new ArrayList<Usuario>();
        Query query = getCurrentSession().createQuery("from Usuario u where u.Username = :username");
        query.setParameter("username", username);
        userList = query.list();
        if (userList.size() > 0){
            return (Usuario) userList.get(0);
        }else{
            return null;
        }
    }

}

servlet的context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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:jee="http://www.springframework.org/schema/jee"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Enable transaction Manager -->
    <tx:annotation-driven/>

    <!-- DataSource JNDI -->
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/paidos" resource-ref="true" />

    <!--  Session factory -->
    <beans:bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" 
        p:dataSource-ref="dataSource"
        p:hibernateProperties-ref="hibernateProperties"
        p:packagesToScan="com.carloscortina.paidosSimple.model" />

    <!--  Hibernate Properties -->
    <util:properties id="hibernateProperties">
        <beans:prop key="hibernate.dialect">
            org.hibernate.dialect.MySQL5InnoDBDialect
        </beans:prop>
        <beans:prop key="hibernate.show_sql">false</beans:prop>
    </util:properties>

    <beans:bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager"
        p:sessionFactory-ref="sessionFactory" />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

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

</beans:beans>

我不知道什么是失踪的,所以任何想法都是受欢迎的,提前谢谢。

编辑: UsuarioDaoImp

package com.carloscortina.paidosSimple.dao;

import java.util.ArrayList;
import java.util.List;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.carloscortina.paidosSimple.model.Usuario;

@Repository
public class UsuarioDaoImp implements UsuarioDao {

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

    @Autowired
    private SessionFactory sessionFactory;

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

    @Override
    public Usuario getUsuario(String username) {
        logger.debug("probando");
        List<Usuario> userList = new ArrayList<Usuario>();
        Query query = getCurrentSession().createQuery("from Usuario u where u.Username = :username");
        query.setParameter("username", username);
        userList = query.list();
        if (userList.size() > 0){
            return (Usuario) userList.get(0);
        }else{
            return null;
        }
    }

}

尝试使用UsuarioDaoImp添加bean后出现此错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usuarioServicioImp': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.carloscortina.paidosSimple.dao.UsuarioDao com.carloscortina.paidosSimple.service.UsuarioServicioImp.usuarioDao; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.carloscortina.paidosSimple.dao.UsuarioDao] is defined: expected single matching bean but found 2: usuarioDaoImp,userDao

UsuarioServiceImp

package com.carloscortina.paidosSimple.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.carloscortina.paidosSimple.dao.UsuarioDao;
import com.carloscortina.paidosSimple.model.Usuario;

@Service
@Transactional
public class UsuarioServicioImp implements UsuarioService{

    @Autowired
    private UsuarioDao usuarioDao;

    @Override
    public Usuario getUsuario(String username) {
        return usuarioDao.getUsuario(username);
    }

}

我认为我对这个主题知之甚少,为什么我跟着一个例子,但我以此结束了,所以如果我没有正确地提供信息或者我是否误解了概念,我会道歉。

弹簧security.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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:jee="http://www.springframework.org/schema/jee"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="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.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">


    <beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean>

    <security:http auto-config="true">
        <security:intercept-url pattern="/sec/moderation.html" access="ROLE_ASISTENTE" />  
        <security:intercept-url pattern="/admin/*" access="ROLE_DOCTOR" />   
        <security:form-login login-page="/user-login.html" 
            default-target-url="/success-login.html" 
            authentication-failure-url="/error-login.html" />  
        <security:logout logout-success-url="/index.html" />
    </security:http>  

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

</beans:beans>  

2 个答案:

答案 0 :(得分:3)

您如何访问CustomUSerDetailsS​​ervice类?我希望你没有在安全配置文件或任何其他弹簧配置中将此类添加为bean?

<强> Editted: 你的服务bean用@service注释,你也用xml声明它,spring创建了两个服务bean,一个基于@service注释(完全填充为autowried),第二个使用xml配置(我假设你没有') t明确地注入dao依赖),所以第二个没有dao对象集。当您使用安全配置中声明的服务bean的bean名称时,您将在调试时将userDao设置为null。

要么在安全xml中注释显式bean定义,请直接使用ref =“customUSerDetailsS​​ervice”,因为@service注释已经在spring上下文中添加了一个带有此名称的bean。

即。在安全配置中注释/删除此行,并且每件事都应该有效。

<beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean>

当您使用@ component / @ service注释bean时,spring会添加一个名称等于short classname的bean(首字母小写),因此名称为“customUserDetailsS​​ervice”的bean已经存在,在xml中显式定义它是覆盖它。

或者明确声明所有bean定义(包括那些依赖项)xml config

答案 1 :(得分:1)

将dao包添加到组件扫描

<context:component-scan base-package="com.carloscortina.paidosSimple, com.carloscortina.paidosSimple.dao" />