java疑难杂症:多线程下@Resource和@Autowired和@Value 注入为null的解决办法

方法一:关于@Resource和@Autowired为null的解决办法

新建一个 ApplicationContext(spring上下文对象) 的工具类SpringContextUtil

public class SpringContextUtil {
    private static ApplicationContext applicationContext;

    // 设置上下文
    public static void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    // 获取上下文
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    // 通过名字获取上下文中的bean
    public static Object getBean(String name) {
        if(name == null || name.length()==0) {
            return null;
        }
        try {
            String beanName = "";
            if(name.length() >1){
                beanName = name.substring(0, 1).toLowerCase() + name.substring(1);
            } else {
                beanName = name.toLowerCase();
            }
            return applicationContext.getBean(beanName);
        } catch (Exception ex){
            ex.printStackTrace();
            return null;
        }
    }

    // 通过类型获取上下文中的bean
    public static <T> T getBean(Class<T> clazz) {
        try {
            return (T) applicationContext.getBean(clazz);
        } catch(Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}

然后在springboot 启动类中注入上下文对象

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MyApplication.class, args);
        SpringContextUtil.setApplicationContext(run);
        
        // 测试
        // 自定义方法调用启动线程
        syncUserTable();
    }
}

/**
* 线程开启方法
**/
private static void syncUserTable() {
	// 实例化线程
    Thread thread = new SyncUserTable();
    // 开启线程
    thread.start();
}

线程类中的run() 方法如下:

@Override
public void run() {
   // 测试mapper 是否可用
   UserMapper userMapper = SpringContextUtil.getBean(UserMapper.class);
   QueryWrapper queryWrapper = new QueryWrapper();
   queryWrapper.eq("name", "张三");
   Integer integer = userMapper.selectCount(queryWrapper);
   System.out.println(integer); // 打印结果:1
}

到此成功获取到用户表中name字段为“张三”的对象数量为1

方法二:多线程下@Value注入失败的解决办法

配合上面在启动类中加入的工具类SpringContextUtil ,从工具类中获取org.springframework.core.env.Environment 对象

Environment env = SpringContextUtil.getBean(Environment.class);
String loginUrl = env.getProperty("api.loginUrl");
System.out.println("loginUrl -->" + loginUrl); // 打印结果: loginUrl -->http://localhost:80

application.yml 如下:

#服务配置
server:
  port: 9002

api:
  loginUrl: 'http://localhost:80'
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值