首页 > 其他分享 >多线程或监听器@Autowired注入null空指针

多线程或监听器@Autowired注入null空指针

时间:2023-05-31 14:25:59浏览次数:30  
标签:null return appCtx springframework static 监听器 import 多线程 public

// 问题:在多线程中使用@Autowired注入IUserService时,userService使用时为null,获取不到bean
// 原因:new thread不在spring容器中,也就无法获得spring中的bean对象;
@Autowired
private IUserService userService;

// 解决:手动获取bean对象
private IUserService userService = AppContextUtils.getBean(IUserService.class);
简单配置类
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 获取bean实例
 */
@Component
public class AppContextUtils implements ApplicationContextAware, BeanDefinitionRegistryPostProcessor {

    private static ApplicationContext appCtx;

    private static BeanDefinitionRegistry beanDefinitionRegistry;

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

    public static ApplicationContext getApplicationContext(){
        return appCtx;
    }

    /**
     * 这是一个便利的方法,帮助我们快速得到一个BEAN
     * @param beanName bean的名字
     * @return 返回一个bean对象
     */
    public static Object getBean( String beanName ) {
        return appCtx.getBean( beanName );
    }

    /**
     * 通过类型获得BEAN
     * @param cls
     * @return
     */
    public static <T> T getBean(Class<T> cls){
        return appCtx.getBean(cls);
    }

    /**
     *
     * @param beanName
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T getBean(String beanName, Class<T> cls){
        return appCtx.getBean(beanName, cls);
    }

    public static String getEnvProp(String key){
        return appCtx.getEnvironment().getProperty(key);
    }

    public static void unRegisterBean(String beanName){
        if(appCtx.containsBean(beanName)) {
            beanDefinitionRegistry.removeBeanDefinition(beanName);
        }
    }

    public static <T> T registerBean(String name, Class<T> clazz, Object... args) {
        if(appCtx.containsBean(name)) {
            Object bean = appCtx.getBean(name);
            if (bean.getClass().isAssignableFrom(clazz)) {
                return (T) bean;
            } else {
                throw new RuntimeException("BeanName 重复 " + name);
            }
        }

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        for (Object arg : args) {
            beanDefinitionBuilder.addConstructorArgValue(arg);
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();

        beanDefinitionRegistry.registerBeanDefinition(name, beanDefinition);
        return appCtx.getBean(name, clazz);
    }

    public static <T> Map<String, T> getBeansOfType(Class<T> cls){
        return appCtx.getBeansOfType(cls);
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        AppContextUtils.beanDefinitionRegistry = beanDefinitionRegistry;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
       //doNothing
    }
}

标签:null,return,appCtx,springframework,static,监听器,import,多线程,public
From: https://www.cnblogs.com/alpari-wang/p/17445957.html

相关文章

  • Java大文件分片上传/多线程上传功能
    ​ 我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。这次项目的需求:支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,ie8,ie9,Chrome,Firefox,360安全浏览器,并且刷新浏览器后仍然能够续传,重启浏览器(关闭......
  • Java大文件分片上传/多线程上传解决方案
    ​ javaweb上传文件上传文件的jsp中的部分上传文件同样可以使用form表单向后端发请求,也可以使用ajax向后端发请求    1.通过form表单向后端发送请求         <formid="postForm"action="${pageContext.request.contextPath}/UploadServlet"method="post"e......
  • 2023-05-30:Redis6.0为什么要引入多线程呢?
    2023-05-30:Redis6.0为什么要引入多线程呢?答案2023-05-30:Redis多线程比单线程性能提升一倍:Redis6.0引入多线程IO特性对性能提升至少是一倍以上。据Redis作者antirez在RedisConf2019分享中介绍,多线程IO特性可以显著提高Redis的性能和吞吐量,实测GET/SET命令在4......
  • 转:多线程详解
    转自:https://juejin.cn/post/71230166680951849331.什么是多线程1.1进程当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。1.2线程线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈......
  • 使用powercli 批量多线程 克隆vsphere虚拟机
    $VMS=import-csv-Path'vm001.csv'$Job=$VMS|ForEach-Object-Parallel{#忽略位$Skip=$($_.skip)if($Skip-eq"yes"){continue}#虚拟机名字$VMname=$($_.name)#资源池名字$Resource_Pool=$($_.res_po......
  • gdb调试c++多线程死锁问题初步
    https://blog.csdn.net/zsiming/article/details/126695393 总结:psaux|grepfilename //找出进程IDtop-HpPID //列出进程号为PID下的所有线程gdbatattchPID //用gdb调试正在运行的进程(进程号为PID)(需要sudo权限)threadapplyallbt //这里涉及2个命令:thr......
  • 为什么HashMap可以存null,而ConcurrentHashMap不可以?
    HashMap中,null可以作为键也可以做为值。而在ConcurrentHashMap中,Key和Value都不允许为null。ConcurrentMap(如ConcurrentHashMap、ConcurrentSkipListMap)不允许使用null值的主要原因是,在非并发的Map中(如HashMap),是可以容忍模糊性(二义性)的,而在并发Map中是无法容忍的。假如说,所有的......
  • C# 多线程
    什么是线程Thread线程是一个可执行路径,它可以独立于其它线程执行。每个线程都在操作系统的进程(Process)内执行,而操作系统进程提供了程序运行的独立环境。单线程应用,在进程的独立环境里只跑一个线程,所以该线程拥有独占权多线程应用,单个进程中会跑多个线程,它们会共享当前的执行......
  • RollingFileAppender[FILE] - openFile(null,true) call failed. java.io.FileNotFoun
          2023-05-2916:25:31[main]ERRORo.s.boot.SpringApplication-Applicationrunfailedjava.lang.IllegalStateException:Logbackconfigurationerrordetected:ERRORinch.qos.logback.core.rolling.RollingFileAppender[FILE]-openFile(null,true)......
  • canal+rabbitmq: Could not convert incoming message with content-type [null]
    SpringBoot整合Canal+RabbitMQ实现监听MySQL数据库同步更新Redis缓存,编写RabbitMQ消费端监听同步缓存。接收消息是字符串返回的是字节数据,eg:-30,-128,-100,-25,-126,-71,-27,-81,-71,-25,-126,-71,-30,-128,-99使用了jackson的converter后,报了如下的异常:Causedby:......