依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 使用 JPA、SpringMVC、Spring

Posted

技术标签:

【中文标题】依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 使用 JPA、SpringMVC、Spring Security【英文标题】:Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true) using JPA,SpringMVC,Spring Security依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 使用 JPA、SpringMVC、Spring Security 【发布时间】:2014-04-28 04:42:16 【问题描述】:

创建名为“loginDetailsS​​ervice”的 bean 时出现以下错误:

错误

  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
    'loginDetailsService': Injection of autowired dependencies failed; nested exception is
     org.springframework.beans.factory.BeanCreationException:Could not autowire field: private         
    com.kns.jk.repository.UserRepository com.kns.jk.service.LoginDetailsService.userRepository;         
    nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
    No qualifying bean of type [com.kns.jk.repository.UserRepository] 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)

我的实体类:

用户.Java

 @Entity
    @Table(name="users")
    public class User  
    @Id
    private int id; 
    @OneToOne(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles",
    joinColumns = @JoinColumn(name="user_id", referencedColumnName="id"),
    inverseJoinColumns = @JoinColumn(name="role_id", referencedColumnName="id"))
    private Role role;
    private String password;
    private String username;
    private String address1;

角色.Java

 @Entity
    @Table(name="roles")
    public class Role 
    @Id
    private int id;      
    private String role;    
    //bi-directional many-to-one association to UserRole    
    @OneToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles",
    joinColumns = @JoinColumn(name="role_id", referencedColumnName="id"),
        inverseJoinColumns = @JoinColumn(name="user_id", referencedColumnName="id"))
    private Set<User> userRoles;
    public Role() 
    
    public int getId() 
        return this.id;
    
    public void setId(int id) 
        this.id = id;
    
    public String getRole() 
        return this.role;
    
    public void setRole(String role) 
        this.role = role;
    
    public Set getUserRoles() 
        return this.userRoles;
    
    public void setUserRoles(Set<User> userRoles) 
        this.userRoles = userRoles;
    

UserRepository.java

  public interface UserRepository extends JpaRepository<User, Integer>    
    public User findByUsername(String username);
    public Role getRole(int id);
    

登录详细信息服务

 import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    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.authority.GrantedAuthorityImpl;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

    import com.kns.jk.repository.UserRepository; 
    import com.kns.jk.model.Role;

    /**
     * A custom @link UserDetailsService where user information
     * is retrieved from a JPA repository
     */

    @Service("loginDetailsService")
    @Transactional(readOnly = true)
    public class LoginDetailsService  implements UserDetailsService  

    @Autowired
    private UserRepository userRepository;

    public UserDetails loadUserByUsername(String username) throws         UsernameNotFoundException 
    try 
    com.kns.jk.model.User domainUser =               userRepository.findByUsername(username);   
            boolean enabled = true;
            boolean accountNonExpired = true;
            boolean credentialsNonExpired = true;
            boolean accountNonLocked = true;

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

         catch (Exception e) 
            throw new RuntimeException(e);
        
       
    /**
     * Retrieves a collection of @link GrantedAuthority based on a numerical role
     * @param role the numerical role
     * @return a collection of @link GrantedAuthority
     */
    public Collection<? extends GrantedAuthority> getAuthorities(Integer role) 
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
        return authList;
    

    /**
     * Converts a numerical role to an equivalent list of roles
     * @param role the numerical role
     * @return list of roles as as a list of @link String
     */
    public List<String> getRoles(Integer role) 
        List<String> roles = new ArrayList<String>();

        if (role.intValue() == 1) 
            roles.add("ROLE_CO");
            roles.add("ROLE_AD");
            roles.add("ROLE_JS");
            roles.add("ROLE_SA");

         else if (role.intValue() == 2) 
            roles.add("ROLE_CO");
        

        return roles;
    

/**
 * Wraps @link String roles to @link SimpleGrantedAuthority objects
 * @param roles @link String of roles
 * @return list of granted authorities
 */
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;



安全配置.xml

 <beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" 
    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-3.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.xsd">
    <http pattern="/resources" security="none" />
    <http auto-config="true" use-expressions="true" >

        <intercept-url pattern="/login" access="permitAll"/>
        <intercept-url pattern="/logout" access="permitAll"/>
        <intercept-url pattern="/denied" access="hasRole('ROLE_JS')"/>
        <intercept-url pattern="/" access="hasRole('ROLE_CO')"/>
        <intercept-url pattern="/user" access="hasAnyRole('ROLE_JS',ROLE_CO)"/>
        <intercept-url pattern="/admin" access="hasAnyRole('ROLE_AD',ROLE_SA)"/>


        <form-login login-page="/login" 
            authentication-failure-url="/login/failure" 
            default-target-url="/"/>

        <access-denied-handler error-page="/denied"/>

        <logout invalidate-session="true" 
            logout-success-url="/logout/success" 
            logout-url="/logout"/>
    </http>

    <authentication-manager>
            <authentication-provider user-service-ref="loginDetailsService">
                    <!-- <password-encoder hash="md5"/> -->
            </authentication-provider>
    </authentication-manager>

    <beans:bean id="loggerListener"         class="org.springframework.security.authentication.event.LoggerListener"/>

    </beans:beans>

mvc-core-config.xml

 <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <import resource="mvc-view-config.xml"/>


    <!--
        - POJOs labeled with the @Controller and @Service annotations are auto-detected.
    -->
    <context:component-scan
            base-package="com.kns.jk.web"/>

    <mvc:annotation-driven />

    <!--  all resources inside folder src/main/webapp/resources are mapped so they can be         refered to inside JSP files
        (see header.jsp for more details) -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <!-- uses WebJars so javascript and CSS libs can be declared as Maven dependencies         (Bootstrap, jQuery...) -->
    <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>

    <mvc:view-controller path="/" view-name="welcome" />

    <!-- bean id="conversionService"         class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="com.kns.jk.web.ResumeTypeFormatter"/>
            </set>
        </property>
    </bean> -->

    <!--
        - Message source for this context, loaded from localized "messages_xx" files.
        - Files are stored inside src/main/resources
    -->
    <bean id="messageSource"         class="org.springframework.context.support.ResourceBundleMessageSource"
          p:basename="messages/messages"/>

    <!--
        - This bean resolves specific types of exceptions to corresponding logical 
        - view names for error views.
    -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- view name resolved using bean of type InternalResourceViewResolver (declared in         mvc-view-config.xml) -->
        <property name="defaultErrorView" value="exception"/>
        <!-- results into 'WEB-INF/jsp/exception.jsp' -->
        <property name="warnLogCategory" value="warn"/>
        <!-- needed otherwise exceptions won't be logged anywhere -->
    </bean>

    </beans>

pom.xml

 <properties>

        <!-- Generic properties -->
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring -->
        <spring-framework.version>3.2.4.RELEASE</spring-framework.version>
        <spring-data-jpa.version>1.3.4.RELEASE</spring-data-jpa.version>

        <!-- Spring Security Version -->
        <springsecurity.version>3.2.2.RELEASE</springsecurity.version>


        <!-- Java EE / Java SE dependencies -->
        <jsp.version>2.2</jsp.version>
        <jstl.version>1.2</jstl.version>
        <servlet.version>2.5</servlet.version>
        <jaxb-impl.version>2.2.7</jaxb-impl.version>

        <!-- Hibernate / JPA -->
        <hibernate.version>4.2.1.Final</hibernate.version>

        <!-- Bean validation -->
        <hibernate-validator.version>4.3.1.Final</hibernate-validator.version>

        <!-- Database access -->
        <tomcat-jdbc.version>7.0.42</tomcat-jdbc.version>
        <ehcache.version>2.6.6</ehcache.version>
        <hsqldb.version>2.3.0</hsqldb.version>

        <!-- AOP -->
        <aspectj.version>1.7.3</aspectj.version>

        <!-- Logging -->
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>

        <!-- RSS -->
        <rome.version>1.0</rome.version>

        <!-- Test -->
        <junit.version>4.11</junit.version>
        <hamcrest.version>1.3</hamcrest.version>

        <!-- Dates -->
        <jodatime-hibernate.version>1.3</jodatime-hibernate.version>
        <jodatime-jsptags.version>1.1.1</jodatime-jsptags.version>
        <jodatime.version>2.2</jodatime.version>
        <jadira-usertype-core.version>3.1.0.CR8</jadira-usertype-core.version>


        <!-- Web dependencies -->
        <webjars-bootstrap.version>2.3.0</webjars-bootstrap.version>
        <webjars-jquery-ui.version>1.9.2</webjars-jquery-ui.version>
        <webjars-jquery.version>1.9.0</webjars-jquery.version>
        <dandelion.datatables.version>0.8.14</dandelion.datatables.version>

        <mysql.version>5.1.22</mysql.version>

    </properties>

不太清楚为什么会发生错误。我已经尝试了互联网上提供的一堆解决方案。

【问题讨论】:

【参考方案1】:

关键在于原来的错误:

NoSuchBeanDefinitionException: 
    No qualifying bean of type [com.kns.jk.repository.UserRepository]

UserRepository 是一个接口,您需要在 mvc-core-config.xml 中的 spring bean 定义中为其声明一个实现

添加类似:

<bean id="userRepository" class="com.kns.jk.repository.UserRepositoryImpl" />

应该做的伎俩。将 UserRepositoryImpl 替换为您的 UserRepository 实现的真实类名。

HTH

【讨论】:

以上是关于依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 使用 JPA、SpringMVC、Spring 的主要内容,如果未能解决你的问题,请参考以下文章

springCould注解和配置以及pom依赖

java @Autowired @Resource @Inject 三个注解的区别

Spring 的这些核心注解你了解吗?

spring常用注解及常用依赖

spring常用注解及常用依赖

@Transient 注解、@org.springframework.data.annotation.Transient 注解、transient 关键字和密码存储