您的位置:首页 > 其它

Shiro Realm @Autowired 注入失败的问题

2016-12-23 13:25 489 查看
最近在折腾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的区别,还是不怎么明白这个问题解决的根本原因。

网上说:

@Autowired默认按类型装配(这个注解是属于spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false如:@Autowired(required=false) 

@Resource 是JDK1.6支持的注解,默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
可能是因为我定义的UserDao是接口类型的,没有办法实例化,但是再一想也不对,在Controller中注入的Service中的dao都是用@Autowire进行注入的,那些就没问题。目前为止还是不明白,先知道怎么解决吧,等明白了,想起来了再来补上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shiro Realm Autowired