Springboot应用启动后自动将jar包中的文件复制到指定位置,例如:springboot在项目启动时,拷贝一份application.yml文件到jar包外指定位置

Springboot应用启动后自动将jar包中的文件复制到指定位置,例如:springboot在项目启动时,拷贝一份application.yml文件到jar包外指定位置

分两种情况:

1.填充普通bean属性之后但在初始化之前拷贝
2.加载bean之前进行拷贝

情况1:填充普通bean属性之后但在初始化之前拷贝

  1. 需求
    我们都知道采用Springboot有一个方便的地方,所有的依赖和静态文件,配置文件等最后都可以打成一个jar文件。在本项目中,为了方便用户的使用,配置文件默认的application.yml,现在需要读取这个文件,保存到指定的位置,这样后期可以对外边的jar包进行修改,而覆盖默认的

  2. 解决办法
    由于是在jar文件中,因为常规的读取办法是读取不到该文件的。所以,在用IDE开发时能正常复制,打成 jar包就无法成功。

    采用ServletContextAware Springboot启动后自动运行
    采用类加载器来读取resources目录下的文件
    采用字节流读取复制到指定文件

  3. 代码
    文件存放位置如图:

@Component
public class TestStarted implements ServletContextAware {
    /**
     * 复制application.ymls文件到项目外的路径cms.yml。
     * 仅当该文件不存在时复制。
     * 在填充普通bean属性之后但在初始化之前调用
     * 类似于initializingbean的afterpropertiesset或自定义init方法的回调
     */
    @Override
    public void setServletContext(ServletContext servletContext) {
        try {
            File dbFile = new File("D:\\project\\other-project\\cms\\adc-cms\\repository\\cms-application.yml");
            if (!dbFile.exists()) {
                //读取的关键步骤
                InputStream fis = this.getClass().getClassLoader().getResourceAsStream("application.yml");
                //创建目录
                File db = new File("D:\\project\\other-project\\cms\\adc-cms\\repository\\cms-application.yml");
                if (!db.exists()) {
                    db.getParentFile().mkdirs();
                }
                dbFile.createNewFile();
                FileOutputStream fos = new FileOutputStream("D:\\project\\other-project\\cms\\adc-cms\\repository\\cms-application.yml");
                byte[] bytes = new byte[1024];
                int len = 0; 
                while ((len = fis.read(bytes)) != -1) {
                    fos.write(bytes, 0, len);
                }

               // System.setProperty("spring.config.location","D:\\project\\other-project\\cms\\adc-cms\\repository\\cms-application.yml");

                fis.close();
                fos.close();
            }

            //System.setProperty("spring.config.location","D:\\project\\other-project\\cms\\adc-cms\\repository\\cms-application.yml");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

情况2.加载bean之前进行拷贝

在启动类中,直接创建文件

@SpringBootApplication
@ServletComponentScan
public class Application {

    public static void main(String[] args) {
        //判断文件是否存在,不存在则创建
        createFile();
        SpringApplication.run(Application.class, args);
    }

     private static void createFile() {
        InputStream fis = null;
        OutputStream fos = null;
        try {
            File dbFile = new File("./config/application.yml");
            if (!dbFile.exists()) {
                dbFile.getParentFile().mkdirs();
                dbFile.createNewFile();
                ClassPathResource resource = new ClassPathResource("application.yml");
                fis = resource.getInputStream();
                fos = new FileOutputStream("./config/application.yml");
                List<String> lines = IOUtils.readLines(fis);
                for(String line : lines){
                    line = line+"\r\n";
                    byte[] bytes = line.getBytes();
                    fos.write(bytes);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(fis != null) {
                    fis.close();
                }
                if(fos != null){
                    fos.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

简单复制文件的方式:
使用Files.copy 来实现

 public static void copyFileNew(){
        //源文件
        File file = new File("src/main/resources/application.yml");
        Path path = file.toPath();
        try {
            //创建目录
            File db = new File("./config/application.yml");
            if (!db.exists()) {
                db.getParentFile().mkdirs();
            }
            Files.copy (path,new FileOutputStream (db));
        } catch (IOException e) {
            e.printStackTrace ();
        }
    }

或者

//底层和上述代码类似
    public static void copyFileNew(){
        Path path = Paths.get ("D://a.log");//源文件
        try {
            Files.copy (path,new FileOutputStream (new File ("D://b.log")));
        } catch (IOException e) {
            e.printStackTrace ();
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值