spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题

前言

  1. 整合有缓存、事务的spring boot项目一切正常。
  2. 在该项目上整合shiro安全框架,发现部分类的缓存Cache不能正常使用。
  3. 然后发现该类的注解基本失效,包括事务Transaction注解。事务不能正常运行。

分析

  1. 注解失效的类,都是在shiro框架中(UserRealm)使用过@Autowire注入的类。
  2. 基本确定是shiro框架与spring框架的BeanFactory有所冲突,导致注入shiro框架的类不能被spring正确初始化。

参考

stackoverflow网站上的一些文章认为,Shiro框架初始化比Spring框架的某些部件早,导致使用@Autowire注入Shiro框架的某些类不能被Spring正确初始化。

文章链接:
https://stackoverflow.com/questions/21512791/spring-service-with-cacheable-methods-gets-initialized-without-cache-when-autowi

解决方法

  1. 在Shiro框架中注入Bean时,不使用@Autowire,使用ApplicationContextRegister.getBean()方法,手动注入bean。保证该方法只有在程序完全启动运行时,才被注入。
  2. 使用@Autowire+@Lazy注解,设置注入到Shiro框架的Bean延时加载(即在第一次使用的时候加载)。

示例

1.Shiro中会出问题的代码

public class MyAuthRealm extends AuthorizingRealm {

    //UserService中的注解可能会出现无效的情况
    @Autowired
    private UserService userService;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken utoken = (UsernamePasswordToken) token;
        String username = utoken.getUsername();
        User user = userService.getUserByName(username);
        return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
    }
}

2.手动注入bean

public class UserRealm extends AuthorizingRealm {
    //该代码仅作手动注入bean的说明,前后略有省略代码
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        Long userId = ShiroUtils.getUserId();
        //这里手动注入MenuService 
        MenuService menuService = ApplicationContextRegister.getBean(MenuService.class);
        Set<String> perms = menuService.listPerms(userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(perms);
        return info;
    }

}

3.延时加载(懒加载)

@Component(value = "myAuthRealm")
public class MyAuthRealm extends AuthorizingRealm {

    //延时加载(懒加载)
    @Autowired
    @Lazy
    private UserService userService;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken utoken = (UsernamePasswordToken) token;
        String username = utoken.getUsername();
        User user = userService.getUserByName(username);
        return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
    }
}
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值