java封装工具类时,static静态方法调用config映射文件获取application.yml配置文件参数(使用@PostConstruct)

目的

       获取配置文件(.yml,.properties )中的配置,配置参数已经封装在了Mqconfig,我们需要在工具类的静态方法中,通过自动注入获取该配置。但是直接注入会报空指针异常。 不想看描述的直接跳    解决办法  


场景描述

我需要封装了一个rocketMQ发送消息工具类MqMsgUtils,需要去调用Mqconfig的参数,Mqconfig主要是映射application.yml中的参数,如果是一般的方法可以直接注入,但是静态方法优先级仅次于构造方法,大于自动注入,所以这里调用会导致自动注入失败为空对象

整个Bean初始化中的执行顺序:

Constructor(构造方法,静态方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

MqConfig 

import com.aliyun.openservices.ons.api.PropertyKeyConst;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
@ConfigurationProperties(prefix = "rocketmq")
@Data
public class MqConfig {

    private String accessKey;
    private String secretKey;
    private String nameSrvAddr;

    private String topic;
    private String groupId;
    private String tag;

    private String orderTopic;
    private String orderGroupId;
    private String orderTag;

    public Properties getMqPropertie() {
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.AccessKey, this.accessKey);
        properties.setProperty(PropertyKeyConst.SecretKey, this.secretKey);
        properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, this.nameSrvAddr);
        return properties;
    }

}

MqMsgUtils  

import com.aliyun.openservices.ons.api.*;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.wjd.op.common.config.MqConfig;
import com.wjd.op.common.rocketMq.MqSendCallBack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.Executors;

/**
 * @program: MqMsgUtils
 * @description: mq消息处理工具类
 * @author: whhh
 * @create: 2021/8/31 16:41
 **/
@Slf4j
@Component
public class MqMsgUtils {
    @Autowired
    private static ProducerBean producerBean;//这里2个静态对象都会报空指针

    @Autowired
    private static  MqConfig config;


    /**
     * @param tag       标签
     * @param msgDetail 消息体,二进制的形式
     * @Author: whhh
     * @Description: 异步发送消息
     * @DateTime: 2021/8/31 16:44
     */
    public static void sendMsgAsync(String tag, byte[] msgDetail) {
        //对于使用异步接口,设置单独的回调处理线程池,拥有更灵活的配置和监控能力。
        producer.setCallbackExecutor(Executors.newFixedThreadPool(10));

        //定义消息体
        Message msg = new Message(mqConfig.getTopic(), tag, msgDetail);
        //在无法正常收到消息情况下,可通过MQ 控制台查询消息并补发
        msg.setKey("ORDERID_100");
        // 发送消息,只要不抛异常就是成功
        try {
            //发送消息并定义毁掉函数
            producer.sendAsync(msg, new MqSendCallBack());
        } catch (ONSClientException e) {
            log.warn("发送失败");
            e.printStackTrace();
        }
    }

}

解决办法

使用@PostConstruct注解,利用该注解的方法在整个Bean初始化中的执行顺序,所以我们使用该注解可以去调用一个init方法初始化我们的普通变量,然后把我们注入的对象赋值给静态对象,代码如下

import com.aliyun.openservices.ons.api.*;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.wjd.op.common.config.MqConfig;
import com.wjd.op.common.rocketMq.MqSendCallBack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.Executors;

/**
 * @program: MqMsgUtils
 * @description: mq消息处理工具类
 * @author: whhh
 * @create: 2021/8/31 16:41
 **/
@Slf4j
@Component
public class MqMsgUtils {
    @Autowired
    private ProducerBean producerBean;

    @Autowired
    private MqConfig config;

    private static ProducerBean producer;

    private static MqConfig mqConfig;



    //重点:
    //我们先利用上面的Autowired注解自动注入2个对象
    //然后利用PostConstruct修饰的普通方法初始化我们的静态变量
    //下面的工具类方法调用静态对象就会初始化了
    /**
    * @Author: whhh
    * @Description: 初始化config和producerBean
    * @DateTime: 2021/9/2 9:59
    */
    @PostConstruct
    private void init(){
        //实际调用的是peoducer,mqConfig
        //自动注入的是producerBean,config
        //注入后将值赋给静态变量
        producer=producerBean;
        mqConfig=config;
    }

    /**
     * @param tag       标签
     * @param msgDetail 消息体,二进制的形式
     * @Author: whhh
     * @Description: 异步发送消息
     * @DateTime: 2021/8/31 16:44
     */
    public static void sendMsgAsync(String tag, byte[] msgDetail) {
        //对于使用异步接口,设置单独的回调处理线程池,拥有更灵活的配置和监控能力。
        producer.setCallbackExecutor(Executors.newFixedThreadPool(10));

        //定义消息体
        Message msg = new Message(mqConfig.getTopic(), tag, msgDetail);
        //在无法正常收到消息情况下,可通过MQ 控制台查询消息并补发
        msg.setKey("ORDERID_100");
        // 发送消息,只要不抛异常就是成功
        try {
            //发送消息并定义毁掉函数
            producer.sendAsync(msg, new MqSendCallBack());
        } catch (ONSClientException e) {
            log.warn("发送失败");
            e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值