assembly打包,多yml文件合并为一个yml文件

2024-02-24 09:52
文章标签 打包 合并 yml assembly

本文主要是介绍assembly打包,多yml文件合并为一个yml文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个接着前一个多个服务合并为一个服务的文章,详解yml配置文件合并的问题

由于每个微服务都有yml配置文件,如果合并打包的话,前一篇文章也说了,相同文件会进行覆盖,所以需要自己实现一个适配器,进行yml文件的合并。使用maven-assembly-plugin进行多文件合并逻辑的实现。

首先新建一个模块,实现yml合并的逻辑。

1、pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version><relativePath/></parent><groupId>com.fql.merge</groupId><artifactId>preHandle</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.apache.maven.plugin-tools</groupId><artifactId>maven-plugin-annotations</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.27</version></dependency></dependencies><build><plugins><plugin><groupId>org.codehaus.plexus</groupId><artifactId>plexus-component-metadata</artifactId><version>2.2.0</version><executions><execution><goals><goal>generate-metadata</goal></goals></execution></executions></plugin></plugins></build>
</project>

合并类实现

package com.lfq.integ.util;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;import org.apache.maven.plugins.assembly.filter.ContainerDescriptorHandler;
import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.components.io.fileselectors.FileInfo;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.IOUtil;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;/*** @author lifengqin*/
@Component(role = ContainerDescriptorHandler.class, hint = "yml-merge", instantiationStrategy = "per-lookup" )
public class MySimpleAggregatingDescriptorHandler implements  ContainerDescriptorHandler, LogEnabled{@SuppressWarnings( "FieldCanBeLocal" )private final String commentChars = "#";private final StringWriter aggregateWriter = new StringWriter();private final List<String> filenames = new ArrayList<>();private String filePattern;private String outputPath;private boolean overrideFilterAction;private Logger logger;private Archiver archiver;private File temp;@Overridepublic void finalizeArchiveCreation(Archiver archiver ){checkConfig();if ( this.outputPath.endsWith( "/" ) ) {throw new ArchiverException( "Cannot write aggregated properties to a directory. "+ "You must specify a file name in the outputPath configuration for this"+ " handler. (handler: " + getClass().getName() );}if ( this.outputPath.startsWith( "/" ) ) {this.outputPath = this.outputPath.substring( 1 );}this.temp = this.writePropertiesFile();this.overrideFilterAction = true;archiver.addFile(this.temp, this.outputPath);this.archiver = archiver;this.overrideFilterAction = false;}private File writePropertiesFile() {File f;Writer writer = null;try {f = File.createTempFile("maven-assembly-plugin", "tmp");f.deleteOnExit();writer = AssemblyFileUtils.isPropertyFile( f )? new OutputStreamWriter( new FileOutputStream( f , true), StandardCharsets.ISO_8859_1 ): new OutputStreamWriter( new FileOutputStream( f , true) );writer.write( "\n\n" );writer.write( aggregateWriter.toString() );writer.close();writer = null;}catch ( final IOException e ) {throw new ArchiverException("Error adding aggregated properties to finalize archive creation. Reason: " + e.getMessage(), e );}finally {IOUtil.close(writer);}return f;}@Overridepublic void finalizeArchiveExtraction( final UnArchiver unarchiver ) {}@Overridepublic List<String> getVirtualFiles() {checkConfig();return Collections.singletonList( outputPath );}@Overridepublic boolean isSelected(final FileInfo fileInfo ) throws IOException {if (fileInfo == null){throw new IllegalStateException("fileInfo not be none");}checkConfig();if ( overrideFilterAction ) {return true;}String name = AssemblyFileUtils.normalizeFileInfo( fileInfo );if ( fileInfo.isFile() && name.matches( filePattern ) ) {String content = readProperties( fileInfo );if (name.matches(".*/application.yml")) {writeFile(content);}return false;}return true;}private void checkConfig() {if ( filePattern == null || outputPath == null ) {throw new IllegalStateException("You must configure filePattern and outputPath in your containerDescriptorHandler declaration." );}}/***读取文件* @param fileInfo* @throws IOException*/private String readProperties( final FileInfo fileInfo ) throws IOException {try (StringWriter writer = new StringWriter();Reader reader = AssemblyFileUtils.isPropertyFile(fileInfo.getName())? new InputStreamReader(fileInfo.getContents(), StandardCharsets.ISO_8859_1): new InputStreamReader(fileInfo.getContents())) {IOUtil.copy(reader, writer);final String content = writer.toString();aggregateWriter.write("\n");aggregateWriter.write(content);return content;}}//输出合并后的yml文件private void writeFile(String content) {Writer writer = null;try {writer = AssemblyFileUtils.isPropertyFile( this.temp )? new OutputStreamWriter( new FileOutputStream( this.temp , false), StandardCharsets.ISO_8859_1 ): new OutputStreamWriter( new FileOutputStream( this.temp, false ) );//去掉{}样式DumperOptions options = new DumperOptions();options.setPrettyFlow(true);options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);// 创建YAML对象Yaml yam = new Yaml(options);Map<Object, Object> mergeYmlMap = new HashMap<>();// 将合并后的YAML文件加载到Map对象中for (Object o : yam.loadAll(String.valueOf(this.aggregateWriter))) {Map<Object, Object> ymlMap = (Map<Object, Object>) o;for (Map.Entry<Object, Object> entry : ymlMap.entrySet()) {if (!mergeYmlMap.containsKey(entry.getKey())) {mergeYmlMap.put(entry.getKey(), entry.getValue());} else if (entry.getValue() instanceof Map){mergeMaps((Map<Object, Object>) mergeYmlMap.get(entry.getKey()), (Map<Object, Object>) entry.getValue());}}}// 保存合并结果到目标文件yam.dump(mergeYmlMap, writer);writer.close();writer = null;}catch ( final IOException e ) {throw new ArchiverException("Error adding aggregated properties to finalize archive creation. Reason: " + e.getMessage(), e );}finally {IOUtil.close( writer );}}private static void mergeMaps(Map<Object, Object> target, Map<Object, Object> source) {for (Map.Entry<Object, Object> entry : source.entrySet()) {if (!target.containsKey(entry.getKey())) {target.put(entry.getKey(), entry.getValue());} else if (entry.getValue() instanceof Map){mergeMaps((Map<Object, Object>) target.get(entry.getKey()), (Map<Object, Object>) entry.getValue());}}}protected final Logger getLogger() {if ( logger == null ) {logger = new ConsoleLogger( Logger.LEVEL_INFO, "" );}return logger;}@Overridepublic void enableLogging( final Logger logger ) {this.logger = logger;}@SuppressWarnings( "UnusedDeclaration" )public String getFilePattern() {return filePattern;}@SuppressWarnings( "UnusedDeclaration" )public void setFilePattern( final String filePattern ) {this.filePattern = filePattern;}@SuppressWarnings( "UnusedDeclaration" )public String getOutputPath() {return outputPath;}@SuppressWarnings( "UnusedDeclaration" )public void setOutputPath( final String outputPath ) {this.outputPath = outputPath;}
}

合并的containerDescriptorHandler写好啦

在pom文件加上模块依赖

<!-- 将解开的执行包与本工程代码合并打包 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.3.0</version><configuration><recompressZippedFiles>false</recompressZippedFiles></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals><configuration><archive><manifestFile>${project.build.directory}/work/addpack/mainweb/META-INF/MANIFEST.MF</manifestFile></archive><descriptors><descriptor>assembly.xml</descriptor>   <!-- 加载指定的assembly配置文件 --></descriptors></configuration></execution></executions> <dependencies><dependency><groupId>com.southgis.ibase</groupId><artifactId>preHandle</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</plugin>

在assembly.xml文件加上containerDescriptorHandler

<containerDescriptorHandlers>
      <containerDescriptorHandler>
         <handlerName>yml-merge</handlerName>
         <configuration>
            <filePattern>.*/application.yml</filePattern>
            <outputPath>BOOT-INF/classes/application.yml</outputPath>
         </configuration>
      </containerDescriptorHandler>
   </containerDescriptorHandlers>

这篇关于assembly打包,多yml文件合并为一个yml文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741720

相关文章

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

Python中合并列表(list)的六种方法小结

《Python中合并列表(list)的六种方法小结》本文主要介绍了Python中合并列表(list)的六种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录一、直接用 + 合并列表二、用 extend() js方法三、用 zip() 函数交叉合并四、用

Maven项目打包时添加本地Jar包的操作步骤

《Maven项目打包时添加本地Jar包的操作步骤》在Maven项目开发中,我们经常会遇到需要引入本地Jar包的场景,比如使用未发布到中央仓库的第三方库或者处理版本冲突的依赖项,本文将详细介绍如何通过M... 目录一、适用场景说明​二、核心操作命令​1. 命令格式解析​2. 实战案例演示​三、项目配置步骤​1

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总

利用Python实现Excel文件智能合并工具

《利用Python实现Excel文件智能合并工具》有时候,我们需要将多个Excel文件按照特定顺序合并成一个文件,这样可以更方便地进行后续的数据处理和分析,下面我们看看如何使用Python实现Exce... 目录运行结果为什么需要这个工具技术实现工具的核心功能代码解析使用示例工具优化与扩展有时候,我们需要将

Python实现获取带合并单元格的表格数据

《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧... 由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_exc

Spring Boot项目打包和运行的操作方法

《SpringBoot项目打包和运行的操作方法》SpringBoot应用内嵌了Web服务器,所以基于SpringBoot开发的web应用也可以独立运行,无须部署到其他Web服务器中,下面以打包dem... 目录一、打包为JAR包并运行1.打包为可执行的 JAR 包2.运行 JAR 包二、打包为WAR包并运行

Python将字库文件打包成可执行文件的常见方法

《Python将字库文件打包成可执行文件的常见方法》在Python打包时,如果你想将字库文件一起打包成一个可执行文件,有几种常见的方法,具体取决于你使用的打包工具,下面就跟随小编一起了解下具体的实现方... 目录使用 PyInstaller基本方法 - 使用 --add-data 参数使用 spec 文件(