记录一次在定时任务中想要使用Springboot多实例的发生的问题

问题描述

有一组数据我需要每次定时任务执行的时候都查一遍数据库拿最新的数据来使用,为了代码的整洁和方便这组数据的参数传递,我将这项数据封装进一个单独的对象中,这组数据的初始化还需要用到mapper,那么这个对象就还得在让Spring来管理,所以我给这个对象加上了@Component注解,这个对象每次任务开始都需要被刷新数据,所以我加上了@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)开启他的多实例,因为Spring默认是单例的

为什么我需要开启多实例呢,如上图,因为我要给属性赋值都是要查询数据库的,并且可能会重复查询多次,所以我的方法会先行判空,只有为空才会查询赋值,所以我为了避免多次重复的查询,来这样设计这个对象。

public void ifSetVillageGuardRuleList(Set<String> carrierNoSet) {
        if (this.villageGuardRuleList == null) {
            this.villageGuardRuleList = tmsVillageGuardRuleMapper.selectListByCarrierCodes(carrierNoSet);
            //分组
            Optional.ofNullable(villageGuardRuleList).ifPresent(b -> {
                this.villageGuardRuleListMap = b.stream().collect(Collectors.groupingBy(TmsVillageGuardRule::getCarrierCode));
            });
        }
    }

测试阶段:

这里填写问题的分析: 以上我开启了我对象的多实例,然后接下来进行测试

@Resource
    private PaymentRules paymentRules1;
    @Resource
    private PaymentRules paymentRules2;

    @Test
    public void demo1() {
        System.out.println(System.identityHashCode(paymentRules1));
        System.out.println(System.identityHashCode(paymentRules2));
    }

一个很简单的测试,我将对象注入两次,然后打印他们的hashCode码,发现确实开启了多实例,以下是输出内容:
在这里插入图片描述


使用阶段:

接下来在定时任务中是这样使用的

@Resource
    private PaymentRules paymentRules;

    @Scheduled(cron = "0/3 * * * * ? ") //每隔三秒执行
    public void test() {
        System.out.println(System.identityHashCode(paymentRules));
    }

但是输出结果却是有问题的~~
在这里插入图片描述
发现输出结果一样,然后才发现,Springboot只在启动的时候注入了一次,后续用到的对象都是一个,/(ㄒoㄒ)/~~,那我搞这个单例不是白瞎嘛!

解决方案:

这里填写该问题的具体解决方案:解决方法很简单,通过Springboot上下文程序,来获取Bean即可,代码如下:

@Resource
    @Resource
    private ApplicationContext context;

    @Scheduled(cron = "0/3 * * * * ? ") //每隔三秒执行
    public void test() {
        PaymentRules bean = context.getBean(PaymentRules.class);
        System.out.println(System.identityHashCode(bean));
    }

输出结果如下:

在这里插入图片描述
如上图所示,每次的对象hash都不一样了,至此完美解决多实例的问题。

感谢大家阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值