ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

not eligible for getting processed by all BeanPostProcessors

2022-06-10 00:33:11  阅读:250  来源: 互联网

标签:getting update userExist BeanPostProcessors user UserService shiroFilter ShiroFi


描述

这个BUG大的起源是我上线以后,在后台看日志的时候发现一行奇怪的INFO日志:

2022-06-09 23:34:24 [restartedMain] [org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:376] INFO  - Bean 'userServiceImpl' of type [com.markerhub.service.impl.UserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

什么?userServiceImpl代理失效了?我于是尝试了一下,果然,这个方法直接不回滚了:

@Override
    @Transactional
    public void addUser(UserVo user) {
        User userExist = getBaseMapper().selectOne(new QueryWrapper<User>().eq("id", user.getId()));

        if (userExist == null) {//添加
            user.setPassword(SecureUtil.md5(user.getPassword()));
            user.setCreated(LocalDateTime.now());
            user.setLastLogin(LocalDateTime.now());
            boolean update = saveOrUpdate(user);
            log.info("添加{}号账号结果:{}", user.getId(), update);
            int i = 1 / 0;
            Assert.isTrue(update, "添加失败");
        } else {//修改

            BeanUtil.copyProperties(user, userExist, "created", "password", "lastLogin", "username", "id");

            boolean update = saveOrUpdate(userExist);

            log.info("修改{}号账号结果:{}", userExist.getId(), update);

            Assert.isTrue(update, "修改失败");
        }

    }

第12行我强行模拟了故障,但是数据库里还是保存成功了。这个是生产上的严重事故。Spring事务默认的传播级别,是当前若存在事务,就加入这个事务。saveOrUpdate是mybatis-plus的方法,已经加上了事务注解,也就是说这里事务本来必须是其作用的。

原理探究

我从网上的一篇文章发现了答案https://blog.csdn.net/feiying0canglang/article/details/119704109,问题的罪魁祸首是Shiro框架。

在使用shiro框架的时候,一般都要新建一个ShiroFilterFactoryBean配置一些配置,例如:

@Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
                                                         ShiroFilterChainDefinition shiroFilterChainDefinition) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", jwtFilter);
        shiroFilter.setFilters(filters);
        Map<String, String> filterMap = shiroFilterChainDefinition.getFilterChainMap();
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

这些本身是一些固定的写法,没有太多可以改的,抄过来就行了。但是问题在于ShiroFilterFactoryBean实现了BeanPostProcessor这个接口:

public class ShiroFilterFactoryBean implements FactoryBean<AbstractShiroFilter>, BeanPostProcessor;

这个接口的实现类会在某种情况下被提前初始化,导致他不会被Sping AOP的动态代理所处理,最后的结果就是事务失效。

从打印日志看到,Realm是没有被代理的,因为Realm依赖了UserService,最后UserService页没有被代理。UserService也可能依赖了其他Service,最后就全都事务失效了。

解决

在UserService上加入@Lazy懒加载模式:

UserService userService;

    @Autowired
    @Lazy
    private void setUserServiceImpl(UserService userService) {
        this.userService = userService;
    }

分析依赖,将提前加载的Service全部懒加载。

标签:getting,update,userExist,BeanPostProcessors,user,UserService,shiroFilter,ShiroFi
来源: https://www.cnblogs.com/LostSecretGarden/p/16361708.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有