Shiro Realm @Autowired 注入失败的问题

最近在折腾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进行注入的,那些就没问题。目前为止还是不明白,先知道怎么解决吧,等明白了,想起来了再来补上。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值