spring boot项目启动时读取静态资源文件,但打包jar包后获取不到路径

spring boot项目启动时读取静态资源文件,但打包jar包后获取不到路径

实现项目启动时调用某方法

实现ApplicationRunner接口、实现CommandLineRunner接口,注意搭配 @Component 注解使用

package com.pantech.cloudmessagehandler.provider;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.util.Map;

/**
 * @author lkh
 * @date 2020/11/26 11:46
 * @description 事件发布对象总入口
 */

@Component
@Slf4j
@Order(value = 1)
public class Publisher implements ApplicationRunner {
    private static Map<String ,String> routingKeyMap;
    
    @Override
    public void run(ApplicationArguments args) {
        try{
            // 读取文件内容
            ClassPathResource classPathResource = new ClassPathResource("eventPublisherConfig.json");
            JSONObject json = JSON.parseObject(IOUtils.toString(new FileInputStream(classPathResource.getFile())));
            //JSONObject转Map
            routingKeyMap= com.alibaba.fastjson.JSON.parseObject(json.toJSONString(), new TypeReference<Map<String, String>>(){});
            log.info("read eventPublisherConfig.json success!");
        }catch (Exception e) {
            log.error("failed to read eventPublisherConfig.json file");
        }
    }
}

代码中 IOUtils 工具类需要引入依赖

        <!--读取配置文件-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>

可以看到该两种方法是在 Application 启动后才执行的。
在这里插入图片描述

由于我开发项目时连接到rabbitMQ,并同时监听了多个队列,就导致 消费消息 在 读取该json文件之前,就导致我使用“routingKeyMap”这个变量值的时候为空,并且设置order值最小都无效,导致控制台报错,所以现在就希望读取静态资源json文件是先于mq连接的。
在这里插入图片描述

实现依赖注入完成后就读取资源文件

使用 @PostConstruct 注解,非spring提供的注解,Java自己的注解

用法:修饰一个非静态的void()方法,会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行,该注解的方法在整个Bean初始化中的执行顺序:

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

@Component
@Slf4j
public class Publisher {
    private Map<String, String> routingKeyMap;
    /**
     * 类加载器时执行初始化
     */
    @PostConstruct
    public void init() {
        this.getConfigMap();
    }
    /**
     * 读取routingkey配置文件-eventPublisherConfig.json
     */
    private void getConfigMap() {
        try {
            // 读取文件内容
            ClassPathResource classPathResource = new ClassPathResource("eventPublisherConfig.json");
            JSONObject json = JSON.parseObject(IOUtils.toString(new FileInputStream(classPathResource.getFile())));
            //JSONObject转Map
            routingKeyMap= com.alibaba.fastjson.JSON.parseObject(json.toJSONString(), new TypeReference<Map<String, String>>(){});
            log.info("read eventPublisherConfig.json success!");
        } catch (Exception e) {
            log.info("failed to read eventPublisherConfig.json file"+e.getMessage());
        }
    }
}

在这里插入图片描述

打包jar包后运行报错:spring :cannot be resolved to absolute file path because it does not reside in the file system: jar

本机可以读取到静态文件,但是打包成jar包无法获取路径

原因:打包后Spring试图访问文件系统路径,但无法访问JAR中的路径。 因此必须使用 resource.getInputStream(),所以不能使用apache 工具包的IOUtils

最终代码:

package com.pantech.cloudmessagehandler.provider;

import com.alibaba.fastjson.JSON;
import com.pantech.cloud.event.publisher.EventPublisher;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;


import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lkh
 * @date 2020/11/26 11:46
 * @description 事件发布对象总入口
 */

@Component
@Slf4j
public class Publisher {
    private Map<String, String> routingKeyMap;
    private final EventPublisher eventPublisher;
    private final AcdmEventPublisher acdmEventPublisher;

    public Publisher(EventPublisher eventPublisher, AcdmEventPublisher acdmEventPublisher) {
        this.eventPublisher = eventPublisher;
        this.acdmEventPublisher = acdmEventPublisher;
    }

    /**
     * 类加载器时执行初始化
     */
    @PostConstruct
    public void init() {
        this.getConfigMap();
    }

    /**
     * 事件发布消息总入口
     *
     * @param routingKey routingKey
     * @param data       map参数
     */
    public void publish(String routingKey, Map<String, Object> data) {
        String publisherHost = routingKeyMap.get(routingKey);
        if (StringUtils.isBlank(publisherHost)) {
            throw new RuntimeException("未配置routingKey至eventPublisherConfig.json文件!");
        }
        switch (publisherHost) {
            case "acdm":
                acdmEventPublisher.publish(routingKey, data);
                break;
            case "fims":
                eventPublisher.publish(routingKey, data);
                break;
            default:
                break;
        }
    }

    /**
     * 读取routingkey配置文件-eventPublisherConfig.json
     */
    private void getConfigMap() {
        try {
            InputStream inputStream = (new ClassPathResource("eventPublisherConfig.json")).getInputStream();
            byte[] bytes;
            bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            String str = new String(bytes);
            routingKeyMap = JSON.parseObject(str, HashMap.class);
            log.info("read eventPublisherConfig.json success!");
        } catch (Exception e) {
            log.info("failed to read eventPublisherConfig.json file"+e.getMessage());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值