Shiro Realm @Autowired 注入失败的问题

来源:互联网 发布:批处理 软件静默卸载 编辑:程序博客网 时间:2024/06/05 03:10

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


0 0
原创粉丝点击