静态类怎么使用@Autowired注入的类

我写了一个工具类然后需要操作数据库,就需要@autowired注入一下,按照网上的方法我写了以下代码

package com.cjbdi.core.extractcenter.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cjbdi.core.entity.NacosModel;
import com.cjbdi.core.mapper.ConfigInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;

@Component
public class ConfigInfoUtils {
    private static Logger logger = LoggerFactory.getLogger(ConfigInfoUtils.class);

    @Autowired
    private ConfigInfoMapper configInfoMapper;

    public static ConfigInfoUtils configInfoUtils;


    @PostConstruct
    public void init(){
        configInfoUtils = this;
        configInfoUtils.configInfoMapper = this.configInfoMapper;
    }

    public JSONObject selectGroupAll(String group){
        List<NacosModel> byGroupAll = configInfoUtils.configInfoMapper.findByGroupAll(group);
        HashMap<String, Object> map = new HashMap<>();
        byGroupAll.stream().forEach(o ->{
            map.put(o.getDataId(),JSONObject.toJSONString(new Yaml().load(o.getContent())));
        });
        return JSONObject.parseObject(JSON.toJSONString(map));
    }

    public JSONObject selectDataId(String dataId, String group){
        String s = configInfoUtils.configInfoMapper.selectDataId(dataId, group);
        return new JSONObject(new Yaml().load(s));
    }
}

我调用是这么调用的

JSONObject caseOneJson = ConfigInfoUtils.configInfoUtils.selectGroupAll("extractor-feature-label").getJSONObject(caseOne);

然后报错
java.lang.NullPointerException
这些是错误

java.lang.NullPointerException
    at com.cjbdi.core.extractcenter.ExtractCasePortrait.<init>(ExtractCasePortrait.java:51)
    at com.cjbdi.core.controller.IntelJudgeController.<init>(IntelJudgeController.java:33)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:204)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1312)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
    at com.cjbdi.core.ExtractFeatureApplication.main(ExtractFeatureApplication.java:25)

我想问一下这静态类要怎么用@autowired注入的类,我这上边的工具类或者调用方式有什么错误,请指教,急

虽然自己引用自己在spring里是允许的,但是我不能理解你这么做的意义。
静态类这么注入

@Autowired
public void setConfigInfoUtils(ConfigInfoUtils configInfoUtils){
    ConfigInfoUtils.configInfoUtils = configInfoUtils;
}

但是你这个空指针是这里报出来的哦
ExtractCasePortrait.java:51

img


这个初始化没用,
自己等于自己;
自己的configInfoMapper 等于自己的configInfoMapper ;
相当于什么都没做,反而给了报错的可能;
静态注入像楼上说的那样

你public static ConfigInfoUtils configInfoUtils;这行代码都没有创建对象,在init方法里面就调用它的属性,就空指针了。
再说了,你这写的啥呀,谁能看得懂,这不被人骂死

难道就只有属性注入嘛,构造器或者set方法,都能给你注入了,关键在调用的地方,是不是早于这个set的回调,早于那就需要调整bean的加载顺序

img

工具类中的静态方法中无法引用spirng容器中的对象,所以我们这里需要一个可以获取spring容器中自己所需要的Bean的对象。
ApplicationContextAware接口,就很好的完成了我们所需要的功能,我们可以获取到spring的ApplicationContext上下文对象,而该对象管理容器中的Bean,这样我们就可以通过该对象去获取到容器中自己想要的Bean了。
下面是一个使用的例子:

@Service
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }
    public static <T> T get(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }
    public static Object get(String name){
        return applicationContext.getBean(name);
    }
}

然后在静态工具类中这样引用就好了

  public void messageArrived(String topic, MqttMessage message) throws Exception {
                    CollectionDao collectionDao = ApplicationContextUtil.get(CollectionDao.class);
                    //subscribe后得到的消息会执行到这里面
                    System.out.println("topic:" + topic);
                    System.out.println("Qos:" + message.getQos());
                    String data = new String(message.getPayload());
                    System.out.println("message content:" + data);
                         //String data1 = "{"lightValue":110.0,"temperature":23.0,"fire":"0"}";
                         JSONObject jsonObject = new JSONObject(data);
                         Double lightValue = (Double)jsonObject.get("lightValue");
                         Double temperature = (Double)jsonObject.get("temperature");
                         String fire = (String)jsonObject.get("fire");
                         Date date = new Date();
                         CollectionData collectionData = new CollectionData();
                         collectionData.setLightValue(lightValue);
                         collectionData.setTemperature(temperature);
                         collectionData.setFire(fire);
                         collectionData.setCollectionTime(date);
                         collectionDao.saveData(collectionData);
                         //collectionService.saveData(collectionData);



                }

楼上说的都很有道理,但是看你写的代码ConfigInfoUtils 这个类也是有@Component注解的,那这个类也由spring管理,需要使用mapper,直接@Autowired就行,init方法和静态变量configInfoUtils直接删除即可,下面几个处理业务的方法中直接使用mapper.方法(),就完成了查询数据库