最近在折腾Shiro这个框架,在折腾的过程中遇到一个问题,怎么都解决不了,最后稀里糊涂地问题就解决了。原因就在于@Autowire和@Resource这两个注解的问题,平时这两个注解都是可以互换的,但是在Shiro中遇到的这个问题,@Autowire与@Resource就有区别了。
了解Shiro的都知道,使用Shiro的时候需要自己定义Realm,通过自己定义的Realm对登录进行验证和授权。在用户登录的时候,使用Shiro进行验证的时候,肯定是需要从数据库中去查询响应的用户表,将账号密码进行对比验证,所有在我们自己定义的Realm中,需要与数据进行连接。因为我使用的是SpringMVC+JPA的框架,所以我直接在自己定义的Realm中通过注解注入了一个userService,使用userService对数据库进行操作。
问题就在于,因为我的userService中使用的userDao并不是一个具体的实现类,而是一个interface,因为我定义的userDao继承了JpaSpecificationExecutor和JpaRepository 接口,原先在UserService中注入UserDao使用的是@Autowire注解,结果启动tomcat的过程中报错,说无法初始化userDao的bean,这个问题困扰了我大半天,各种网上找解决方案,问人,都没结果。后来不知道为什么,稀里糊涂的就把UserService中UserDao上的@Autowire这个注解换成了@Resource注解,问题居然就这么解决了,使用了一下,发现没有问题。
这是我自己定义的Realm的代码:
package com.sg.shirotest;
import com.sg.model.UserEntity;
import com.sg.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Set<String> roleNames = new HashSet<String>();
Set<String> permissions = new HashSet<String>();
roleNames.add("admin");//添加角色
permissions.add("admin.html"); //添加权限
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
/**
* 登录验证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
UserEntity user = this.userService.getUserByAccount(token.getUsername());
if(user != null){
return new SimpleAuthenticationInfo(user.getAccount(),user.getPassword(),getName());
}else{
throw new AuthenticationException();
}
}
}
这是我的UserService的代码:
package com.sg.service;
import com.sg.model.Role;
import com.sg.model.UserEntity;
import com.sg.repository.UserDao;
import com.sg.web.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by sg on 2016/7/19.
*/
@Component
@Transactional
public class UserService {
@Resource
private UserDao userDao;
public void saveUser(UserEntity user){
this.userDao.save(user);
}
public void deleteUser(UserEntity user){
this.userDao.delete(user);
}
public UserEntity getUserById(Long id){
return this.userDao.findOne(id);
}
public List<UserEntity> getAllUser(){
return this.userDao.findAll();
}
public UserEntity getUserByAccount(String account){
return this.userDao.getUserByAccount(account);
}
public Page<UserEntity> getPageUserByParams(int pageNumber, int pageSize, String sortName, String sortType, Map<String, String> params) {
List<SearchFilter> filters = new ArrayList<SearchFilter>();
if (params.get("account") != null) {
filters.add(new SearchFilter("account", SearchFilter.Operator.LIKE, params.get("account")));
}
filters.add(new SearchFilter("state", SearchFilter.Operator.EQ,1));
Specification<UserEntity> spec = DynamicSpecifications.bySearchFilter(filters,
UserEntity.class);
// 分页排序处理
Sort sort = new Sort(StringUtils.getSortType(sortType), sortName);
PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sort);
return this.userDao.findAll(spec, pageRequest);
}
}
这是我的UserDao的代码:
package com.sg.repository;
import com.sg.model.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
/**
* Created by sg on 2016/7/19.
*/
public interface UserDao extends JpaSpecificationExecutor<UserEntity>,JpaRepository<UserEntity,Long> {
@Query("select user from UserEntity user where user.account = ?1 and user.state = 1")
UserEntity getUserByAccount(String account);
}
去网上找了一下为什么,看到别人写的@Autowire与@Resource的区别,还是不怎么明白这个问题解决的根本原因。
网上说: