依赖注解:@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 【问题描述】:创建名为“loginDetailsService”的 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 的主要内容,如果未能解决你的问题,请参考以下文章
java @Autowired @Resource @Inject 三个注解的区别
@Transient 注解、@org.springframework.data.annotation.Transient 注解、transient 关键字和密码存储