本文主要是介绍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文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!