zoukankan      html  css  js  c++  java
  • 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());
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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;
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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());
        }
    }
  • 相关阅读:
    如何在linux系统中设置静态ip地址
    spring 学习
    java 反射机制和invoke方法
    CentoS7装机
    eclipse 添加jar包的方式
    No-args constructor for class does not exist. Register an InstanceCreator with G
    freemarker页面如何获取绝对路径basePath
    MySQL备份还原
    MySQL用户授权与权限
    CentOS7修改SSH远程连接端口
  • 原文地址:https://www.cnblogs.com/root429/p/9251328.html
Copyright © 2011-2022 走看看