SpringBoot Bean @Autowired 多例问题

在使用SpringBoot写一个异步定时器调用时发现了一个问题。即对于相同的对象使用不同的入参进行调用。

但发现其中有一个异步进程一直没有得到调用。经过分析,发现SpringBoot @Autowired有一个隐藏的信息,他是默认单例执行的。

所以对于2个进程中的laserService实例,实际上使用的是相同的对象

 @Autowired
  LaserService laserService;

 @Async
    @Scheduled(cron = "0 5 * * * ?")
    public void scheduled(){
        String host = "1.1.1.1";
    boolean result = laserService.Update(host);
}

 @Async
    @Scheduled(cron = "0 5 * * * ?")
    public void scheduled2(){
        String host = "2.2.2.2";
    boolean result = laserService.Update(host);
}

参考https://blog.csdn.net/baidu_36528788/article/details/81237922​​​​​

需要使用getBean的方式进行多例

​​​​​​@Scope("prototype")的正确用法——解决Bean的多例问题 - adaandy - 博客园

@Scope("prototype")的正确用法——解决Bean的多例问题 - 简书

最后参考上述文章,由于我是定时任务,未使用controller,所以直接在Impl层的class上增加@Scope("prototype"),并在TimerUtils调用时使用getBean模式:

      LaserService laserservice1 = SpringBeanUtil.getBean(LaserService.class);
            boolean result = laserservice1.UpdateOdps(host);

新增一个getBean的class

package com.net.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


@Component
public class SpringBeanUtil implements ApplicationContextAware {

    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

另一种更简洁的方法是:放弃注解。直接将class作为类进行调用 直接new Impl

但这种方式会导致其他@Autowired注解失效。

原因不明。

怀疑为创建新的实例时,引用了相同的单例子实例存在冲突

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值