Java Maven中自动代码检查插件详细介绍

文章目录

  • Checkstyle
      • 主要特点
      • 使用场景
      • 配置与使用
        • checkstyle.xml
        • suppressions.xml
      • 验证
        • 打包时验证
        • 执行命令验证
  • Spotless
    • 配置文件内容
        • Java配置部分
        • POM 配置部分
        • Markdown 配置部分
        • Up to Date Checking
        • 执行部分
      • 验证
      • 打包时验证
      • 在插件中执行命令验证
    • Checkstyle + Spotless 结合
      • checkstyle.xml
      • suppressions.xml
      • pom.xml

Checkstyle

Checkstyle 是一个开源的代码质量管理工具,主要用于帮助程序员遵守编程标准和代码规范。它通过自动化检查Java源代码,识别出不符合预定义或自定义编码规则的部分,从而提升代码的可读性、一致性和维护性。Checkstyle 支持广泛的检查规则,包括但不限于命名约定、类设计、 Imports组织、空白使用、代码格式化等。

主要特点

  1. 丰富的规则集:Checkstyle 提供了一套全面的内置规则,涵盖了从文件命名、缩进、行长度、注释风格到复杂度测量等多方面的检查。用户可以根据需要启用或禁用这些规则。

  2. 高度可配置性:除了使用默认规则外,用户还可以创建自定义规则集,调整现有规则的属性,或者完全编写自己的检查规则,以适应特定项目或团队的编码标准。

  3. 集成简便:Checkstyle 可以轻松地集成到多种开发环境和构建流程中,比如Eclipse、IntelliJ IDEA、Maven、Gradle等。这样可以在代码提交前、编译时或持续集成过程中自动执行检查。

  4. 即时反馈:集成到IDE时,Checkstyle 能够实时提供反馈,开发者在编码过程中就能看到不合规的代码提示,及时修正。

  5. 报告生成:Checkstyle 可以生成详细的报告,指出哪些文件、哪些行存在违规情况,甚至可以集成到持续集成服务器上,为团队提供统一的代码质量视图。

使用场景

  • 团队协作:确保整个团队遵循统一的编码规范,减少代码审查中的样式争议。
  • 项目维护:对于长期维护的项目,保持代码风格的一致性,提高代码的可读性和可维护性。
  • 新开发者培训:帮助新加入的开发者快速了解并遵循项目的编码规范。
  • 自动化代码质量控制:在持续集成和部署流程中,作为代码质量检查的一环,自动化拒绝不符合规范的代码提交。

配置与使用

Checkstyle 的配置文件通常是一个XML文件,定义了启用的检查规则及其参数。

在项目的pom.xml中中配置依赖

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-checkstyle-plugin</artifactId><version>3.3.0</version><configuration><configLocation>./script/checkstyle/checkstyle.xml</configLocation><suppressionsLocation>./script/checkstyle/suppressions.xml</suppressionsLocation><includeTestSourceDirectory>true</includeTestSourceDirectory><consoleOutput>true</consoleOutput><failsOnError>true</failsOnError><linkXRef>false</linkXRef></configuration><executions><execution><id>validate</id><phase>validate</phase><goals><goal>check</goal></goals></execution></executions></plugin></plugins></build>

上文指定了两个风格配置文件,可以根据自己需求去自定义。

checkstyle.xml
<?xml version="1.0"?>
<!--~ Licensed to the Apache Software Foundation (ASF) under one or more~ contributor license agreements.  See the NOTICE file distributed with~ this work for additional information regarding copyright ownership.~ The ASF licenses this file to You under the Apache License, Version 2.0~ (the "License"); you may not use this file except in compliance with~ the License.  You may obtain a copy of the License at~~     http://www.apache.org/licenses/LICENSE-2.0~~ Unless required by applicable law or agreed to in writing, software~ distributed under the License is distributed on an "AS IS" BASIS,~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~ See the License for the specific language governing permissions and~ limitations under the License.--><!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"><module name="Checker"><module name="SuppressWarningsFilter"/><property name="charset" value="UTF-8"/><property name="severity" value="error"/><property name="fileExtensions" value="java, properties, xml"/><!-- Excludes all 'module-info.java' files              --><!-- See https://checkstyle.org/config_filefilters.html --><module name="BeforeExecutionExclusionFileFilter"><property name="fileNamePattern" value="module\-info\.java$"/></module><module name="SuppressionFilter"><property name="file" value="${org.checkstyle.google.suppressionfilter.config}"default="checkstyle-suppressions.xml"/><property name="optional" value="true"/></module><module name="LineLength"><property name="fileExtensions" value="java"/><property name="max" value="200"/><property name="ignorePattern"value="^package.*|^import.*|a href|href|http://|https://|ftp://"/></module><module name="TreeWalker"><module name="OuterTypeFilename"/><module name="IllegalTokenText"><property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/><property name="format"value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/><property name="message"value="Consider using special escape sequence instead of octal value or Unicode escaped value."/></module><module name="AvoidEscapedUnicodeCharacters"><property name="allowEscapesForControlCharacters" value="true"/><property name="allowByTailComment" value="true"/><property name="allowNonPrintableEscapes" value="true"/></module><module name="OneTopLevelClass"/><module name="NoLineWrap"><property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/></module><module name="EmptyBlock"><property name="option" value="TEXT"/><property name="tokens"value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/></module><module name="SuppressionXpathSingleFilter"><property name="id" value="RightCurlyAlone"/><property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]or preceding-sibling::*[last()][self::LCURLY]]"/></module><module name="WhitespaceAfter"><property name="tokens"value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE,LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/></module><module name="OneStatementPerLine"/><module name="MultipleVariableDeclarations"/><module name="ArrayTypeStyle"/><module name="MissingSwitchDefault"/><module name="FallThrough"/><module name="UpperEll"/><module name="UnusedImports"/><module name="EmptyLineSeparator"><property name="tokens"value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,COMPACT_CTOR_DEF"/><property name="allowNoEmptyLineBetweenFields" value="true"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapDot"/><property name="tokens" value="DOT"/><property name="option" value="nl"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapEllipsis"/><property name="tokens" value="ELLIPSIS"/><property name="option" value="EOL"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapArrayDeclarator"/><property name="tokens" value="ARRAY_DECLARATOR"/><property name="option" value="EOL"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapMethodRef"/><property name="tokens" value="METHOD_REF"/><property name="option" value="nl"/></module><module name="PackageName"><property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/><message key="name.invalidPattern"value="Package name ''{0}'' must match pattern ''{1}''."/></module><module name="TypeName"><property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,ANNOTATION_DEF, RECORD_DEF"/><message key="name.invalidPattern"value="Type name ''{0}'' must match pattern ''{1}''."/></module><module name="MemberName"><property name="format" value="^[a-z][a-z0-9]?[a-zA-Z0-9]*$"/><message key="name.invalidPattern"value="Member name ''{0}'' must match pattern ''{1}''."/></module><module name="ParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="LambdaParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="CatchParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Catch parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="LocalVariableName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Local variable name ''{0}'' must match pattern ''{1}''."/></module><module name="PatternVariableName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Pattern variable name ''{0}'' must match pattern ''{1}''."/></module><module name="ClassTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Class type name ''{0}'' must match pattern ''{1}''."/></module><module name="RecordComponentName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" /><message key="name.invalidPattern" value="Record component name ''{0}'' must match pattern ''{1}''." /></module><module name="RecordTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Record type name ''{0}'' must match pattern ''{1}''."/></module><module name="RecordTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Record type name ''{0}'' must match pattern ''{1}''."/></module><module name="MethodTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Method type name ''{0}'' must match pattern ''{1}''."/></module><module name="InterfaceTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Interface type name ''{0}'' must match pattern ''{1}''."/></module><module name="Indentation"><property name="basicOffset" value="4"/><property name="braceAdjustment" value="0"/><property name="caseIndent" value="4"/><property name="throwsIndent" value="2"/><property name="lineWrappingIndentation" value="4"/><property name="arrayInitIndent" value="8"/></module><module name="AbbreviationAsWordInName"><property name="ignoreFinal" value="false"/><property name="allowedAbbreviationLength" value="0"/><property name="allowedAbbreviations"value="XML, URL, ID, FTP, DTO, VO, DO, TO, PO, BO, POJO, HTTP, IP, IE"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,RECORD_COMPONENT_DEF"/></module><module name="NoWhitespaceBefore"><property name="tokens"value="COMMA, SEMI, POST_INC, POST_DEC, DOT,LABELED_STAT, METHOD_REF"/><property name="allowLineBreaks" value="true"/></module><module name="ParenPad"><property name="tokens"value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,RECORD_DEF"/></module><module name="AnnotationLocation"><property name="id" value="AnnotationLocationMostCases"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,RECORD_DEF, COMPACT_CTOR_DEF"/></module><module name="AnnotationLocation"><property name="id" value="AnnotationLocationVariables"/><property name="tokens" value="VARIABLE_DEF"/><property name="allowSamelineMultipleAnnotations" value="true"/></module><module name="NonEmptyAtclauseDescription"/><module name="InvalidJavadocPosition"/><module name="JavadocTagContinuationIndentation"><property name="offset" value="0"/></module><module name="AtclauseOrder"><property name="tagOrder" value="@param, @return, @throws, @deprecated"/><property name="target"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/></module><module name="JavadocMethod"><property name="accessModifiers" value="public"/><property name="allowMissingParamTags" value="true"/><property name="allowMissingReturnTag" value="true"/><property name="allowedAnnotations" value="Override, Test"/><property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/></module><module name="MissingJavadocType"><property name="scope" value="protected"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,RECORD_DEF, ANNOTATION_DEF"/><property name="excludeScope" value="nothing"/></module><module name="MethodName"><property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/><message key="name.invalidPattern"value="Method name ''{0}'' must match pattern ''{1}''."/></module><module name="SingleLineJavadoc"><property name="ignoreInlineTags" value="false"/></module><module name="EmptyCatchBlock"><property name="exceptionVariableName" value="ignore"/></module><module name="CommentsIndentation"><property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/></module><module name="SuppressionXpathFilter"><property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"default="checkstyle-xpath-suppressions.xml"/><property name="optional" value="true"/></module><module name="SuppressWarningsHolder"/><module name="SuppressionCommentFilter"><property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/><property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/><property name="checkFormat" value="$1"/></module><module name="SuppressWithNearbyCommentFilter"><property name="commentFormat" value="CHECKSTYLE.SUPPRESS\: ([\w\|]+)"/><property name="checkFormat" value="$1"/><property name="influenceFormat" value="1"/></module><module name="RegexpSinglelineJava"><property name="format" value="^.*(@author|@date).*" /><property name="message" value="Java file header cannot contain @author or @date" /></module><!--IMPORT CHECKS--><module name="RedundantImport"><!-- Checks for redundant import statements. --><property name="severity" value="error"/><message key="import.redundancy"value="Redundant import {0}."/></module><module name="ImportOrder"><property name="severity" value="error"/><!-- This ensures that static imports go first. --><property name="option" value="top"/><property name="sortStaticImportsAlphabetically" value="true"/><property name="tokens" value="STATIC_IMPORT, IMPORT"/><message key="import.ordering"value="Import {0} appears after other imports that it should precede"/></module><module name="AvoidStarImport"><property name="severity" value="error"/></module><module name="RedundantModifier"><!-- Checks for redundant modifiers on various symbol definitions.See: http://checkstyle.sourceforge.net/config_modifier.html#RedundantModifier--><property name="tokens" value="METHOD_DEF, VARIABLE_DEF, ANNOTATION_FIELD_DEF, INTERFACE_DEF, CLASS_DEF, ENUM_DEF"/></module><module name="UnusedImports"><property name="severity" value="error"/><property name="processJavadoc" value="true"/><message key="import.unused"value="Unused import: {0}."/></module><!--WHITESPACE CHECKS--><module name="WhitespaceAround"><!-- Checks that various tokens are surrounded by whitespace.This includes most binary operators and keywords followedby regular or curly braces.--><property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/><property name="severity" value="error"/></module><module name="WhitespaceAfter"><!-- Checks that commas, semicolons and typecasts are followed bywhitespace.--><property name="tokens" value="COMMA, SEMI, TYPECAST"/></module><module name="NoWhitespaceAfter"><!-- Checks that there is no whitespace after various unary operators.Linebreaks are allowed.--><property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,UNARY_PLUS"/><property name="allowLineBreaks" value="true"/><property name="severity" value="error"/></module><module name="NoWhitespaceBefore"><!-- Checks that there is no whitespace before various unary operators.Linebreaks are allowed.--><property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/><property name="allowLineBreaks" value="true"/><property name="severity" value="error"/></module><module name="OperatorWrap"><!-- Checks that operators like + and ? appear at newlines rather thanat the end of the previous line.--><property name="option" value="NL"/><property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL,GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD,NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/></module><module name="OperatorWrap"><!-- Checks that assignment operators are at the end of the line. --><property name="option" value="eol"/><property name="tokens" value="ASSIGN"/></module><module name="ParenPad"><!-- Checks that there is no whitespace before close parens or afteropen parens.--><property name="severity" value="error"/></module><module name="ModifierOrder"/></module>
</module>
suppressions.xml
<?xml version="1.0"?>
<!--Licensed to the Apache Software Foundation (ASF) under oneor more contributor license agreements.  See the NOTICE filedistributed with this work for additional informationregarding copyright ownership.  The ASF licenses this fileto you under the Apache License, Version 2.0 (the"License"); you may not use this file except in compliancewith the License.  You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing,software distributed under the License is distributed on an"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.  See the License for thespecific language governing permissions and limitationsunder the License.-->
<!DOCTYPE suppressions PUBLIC"-//Puppy Crawl//DTD Suppressions 1.1//EN""http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"><suppressions><suppress checks="JavadocPackage" files=".*[\\/]src[\\/]test[\\/].*"/><suppress checks="JavadocPackage" files=".*[\\/]maven-archetypes[\\/].*"/><suppress checks="JavadocPackage" files=".*[\\/]examples[\\/].*"/><!-- suppress javadoc check for impl classes and package-info.java --><suppress checks="JavadocType" files=".*Impl\.java$" /><suppress checks="JavadocStyle" files=".+[\\/]package-info\.java$" /><!-- suppress all checks in the generated directories --><suppress checks=".*" files=".+[\\/]generated[\\/].+\.java"/><suppress checks=".*" files=".+[\\/]generated-sources[\\/].+\.java"/><suppress checks=".*" files=".+[\\/]generated-test-sources[\\/].+\.java"/><!-- suppress most all checks expect below--><suppress checks="^(?!.*(UnusedImports|IllegalImport)).*$" files=".*[\\/]src[\\/]test[\\/].*"/>
</suppressions>

tips: 在项目最外层pom.xml中引入依赖就可以,子项目可以自动继承该配置

验证

打包时验证

mvn package时,会自动运行检查,如果有不符合风格的会提示打包异常。此时需要手动去修改,checkstyle插件不具备自动修复能力。

如:

[INFO] 开始检查……
[ERROR] /Users/mac/IdeaProjects/all-in-one/redis/xxx:12:1: Import java.util.List appears after other imports that it should precede [ImportOrder]
执行命令验证

在这里插入图片描述

这四个命令都涉及到 Checkstyle 工具的不同功能和用途:

  1. checkstyle:check
    • 这个命令用于执行 Checkstyle 插件的 check 目标。执行此命令时,Checkstyle 插件将会检查你的代码是否符合预定义的代码规范(规则)。如果代码中存在不符合规范的地方,会输出相应的警告或错误信息。
  2. checkstyle:checkstyle
    • 这个命令用于生成 Checkstyle 报告。执行此命令后,Checkstyle 插件会分析代码,并生成一个详细的报告,展示代码中哪些地方违反了规范,以及如何修正这些问题。
  3. checkstyle:checkstyle-aggregate
    • 这个命令与上一个命令类似,也是生成 Checkstyle 报告,但它会在聚合项目(多个子项目组成的项目)的上下文中运行。这意味着它会汇总所有子项目的检查结果,并生成一个总体的报告。
  4. checkstyle:help
    • 这个命令用于查看 Checkstyle 插件的帮助文档。执行此命令后,会列出 Checkstyle 插件支持的所有命令和参数选项,帮助你理解如何使用 Checkstyle 插件及其配置选项。

Spotless

配置文件内容

            <plugin><groupId>com.diffplug.spotless</groupId><artifactId>spotless-maven-plugin</artifactId><version>2.29.0</version><configuration><skip>false</skip><java><excludes><exclude>src/main/java/wiki/hadoop/test/*.*</exclude></excludes><googleJavaFormat><version>1.7</version><style>AOSP</style></googleJavaFormat><removeUnusedImports /><formatAnnotations /><importOrder><order>wiki.hadoop,org.apache,org,,javax,java,\#</order></importOrder><replaceRegex><name>Remove wildcard imports</name><searchRegex>import\s+(static)*\s*[^\*\s]+\*;(\r\n|\r|\n)</searchRegex><replacement>$1</replacement></replaceRegex><replaceRegex><name>Block hutool</name><searchRegex>import\s+cn\.hutool\.[^\*\s]*(|\*);(\r\n|\r|\n)</searchRegex><replacement>$1</replacement></replaceRegex></java><pom><sortPom><encoding>UTF-8</encoding><nrOfIndentSpace>4</nrOfIndentSpace><keepBlankLines>true</keepBlankLines><indentBlankLines>false</indentBlankLines><indentSchemaLocation>true</indentSchemaLocation><spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement><sortModules>false</sortModules><sortExecutions>false</sortExecutions><predefinedSortOrder>custom_1</predefinedSortOrder><expandEmptyElements>false</expandEmptyElements><sortProperties>false</sortProperties></sortPom><replace><name>Leading blank line</name><search>project</search><replacement>project</replacement></replace></pom><markdown><includes><include>docs/**/*.md</include></includes><excludes><exclude>**/.github/**/*.md</exclude></excludes><flexmark /></markdown><upToDateChecking><enabled>true</enabled></upToDateChecking></configuration><executions><execution><id>spotless-check</id><goals><goal>check</goal></goals><phase>validate</phase></execution></executions></plugin>
Java配置部分
  • skip: 是否跳过Spotless插件的执行,这里设置为 false 表示不跳过。

  • excludes: 排除特定文件或目录,这里排除了 src/main/java/wiki/hadoop/test 目录下的所有文件。

  • googleJavaFormat: 使用 Google Java 格式化工具,版本为 1.7,样式为 AOSP

  • removeUnusedImports: 移除未使用的import语句。

  • formatAnnotations: 格式化注解。

  • importOrder: 定义import语句的顺序,确保不同来源的import语句有固定的顺序,便于维护和阅读。

    <importOrder><order>wiki.hadoop,org.apache,org,,javax,java,\#</order>
    </importOrder>
    
    • 定义了import语句的排序规则,顺序为:
      • wiki.hadoop
      • org.apache
      • org
      • 空 (所有未配置的包)
      • javax
      • java
      • # (标识所有静态导入)
  • replaceRegex: 使用正则表达式替换特定内容:

    • Remove wildcard imports: 移除使用通配符的import。
    • Block powermock: 阻止使用 powermock 库。(禁止使用哪些包)
POM 配置部分
  1. sortPom: POM文件排序配置,包括编码、缩进等细节:

    • encoding: 文件编码,设置为 UTF-8
    • nrOfIndentSpace: 缩进空格数,设置为 4
    • keepBlankLines: 是否保留空行,设置为 true
    • indentBlankLines: 是否缩进空行,设置为 false
    • indentSchemaLocation: 是否缩进 schema 位置,设置为 true
    • spaceBeforeCloseEmptyElement: 是否在空元素闭合前留空格,设置为 true
    • sortModules: 是否排序模块,设置为 false
    • sortExecutions: 是否排序执行,设置为 false
    • predefinedSortOrder: 预定义排序顺序,设置为 custom_1
    • expandEmptyElements: 是否展开空元素,设置为 false
    • sortProperties: 是否排序属性,设置为 false
  2. replace: 替换特定的内容,确保项目标记没有前导空白行。

Markdown 配置部分
  1. includesexcludes: 指定包含和排除的Markdown文件。
  2. flexmark: 使用Flexmark格式化Markdown文件。
Up to Date Checking
  • enabled: 是否启用最新检查,这里设置为 true
执行部分
<executions><execution><id>spotless-check</id><goals><goal>check</goal></goals><phase>validate</phase></execution>
</executions>

定义了一个执行阶段 validate,在这个阶段执行 spotless:check 目标来检查代码格式。

验证

打包时验证

默认打包时会自动验证

在插件中执行命令验证

在这里插入图片描述

执行 mvn spotless:apply 自动修改代码

执行 mvn spotless:check 检查代码


Checkstyle + Spotless 结合

checkstyle.xml

在项目根目录创建文件script/checkstyle/checkstyle.xml

<?xml version="1.0"?>
<!--~ Licensed to the Apache Software Foundation (ASF) under one or more~ contributor license agreements.  See the NOTICE file distributed with~ this work for additional information regarding copyright ownership.~ The ASF licenses this file to You under the Apache License, Version 2.0~ (the "License"); you may not use this file except in compliance with~ the License.  You may obtain a copy of the License at~~     http://www.apache.org/licenses/LICENSE-2.0~~ Unless required by applicable law or agreed to in writing, software~ distributed under the License is distributed on an "AS IS" BASIS,~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~ See the License for the specific language governing permissions and~ limitations under the License.--><!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"><module name="Checker"><module name="SuppressWarningsFilter"/><property name="charset" value="UTF-8"/><property name="severity" value="error"/><property name="fileExtensions" value="java, properties, xml"/><!-- Excludes all 'module-info.java' files              --><!-- See https://checkstyle.org/config_filefilters.html --><module name="BeforeExecutionExclusionFileFilter"><property name="fileNamePattern" value="module\-info\.java$"/></module><module name="SuppressionFilter"><property name="file" value="${org.checkstyle.google.suppressionfilter.config}"default="checkstyle-suppressions.xml"/><property name="optional" value="true"/></module><module name="LineLength"><property name="fileExtensions" value="java"/><property name="max" value="500"/><property name="ignorePattern"value="^package.*|^import.*|a href|href|http://|https://|ftp://"/></module><module name="TreeWalker"><module name="OuterTypeFilename"/><module name="IllegalTokenText"><property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/><property name="format"value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/><property name="message"value="Consider using special escape sequence instead of octal value or Unicode escaped value."/></module><module name="AvoidEscapedUnicodeCharacters"><property name="allowEscapesForControlCharacters" value="true"/><property name="allowByTailComment" value="true"/><property name="allowNonPrintableEscapes" value="true"/></module><module name="OneTopLevelClass"/><module name="NoLineWrap"><property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/></module><module name="EmptyBlock"><property name="option" value="TEXT"/><property name="tokens"value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/></module><module name="SuppressionXpathSingleFilter"><property name="id" value="RightCurlyAlone"/><property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]or preceding-sibling::*[last()][self::LCURLY]]"/></module><module name="WhitespaceAfter"><property name="tokens"value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE,LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/></module><module name="OneStatementPerLine"/><module name="MultipleVariableDeclarations"/><module name="ArrayTypeStyle"/><module name="MissingSwitchDefault"/><module name="FallThrough"/><module name="UpperEll"/><module name="UnusedImports"/><module name="EmptyLineSeparator"><property name="tokens"value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,COMPACT_CTOR_DEF"/><property name="allowNoEmptyLineBetweenFields" value="true"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapDot"/><property name="tokens" value="DOT"/><property name="option" value="nl"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapEllipsis"/><property name="tokens" value="ELLIPSIS"/><property name="option" value="EOL"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapArrayDeclarator"/><property name="tokens" value="ARRAY_DECLARATOR"/><property name="option" value="EOL"/></module><module name="SeparatorWrap"><property name="id" value="SeparatorWrapMethodRef"/><property name="tokens" value="METHOD_REF"/><property name="option" value="nl"/></module><module name="PackageName"><property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/><message key="name.invalidPattern"value="Package name ''{0}'' must match pattern ''{1}''."/></module><module name="TypeName"><property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,ANNOTATION_DEF, RECORD_DEF"/><message key="name.invalidPattern"value="Type name ''{0}'' must match pattern ''{1}''."/></module><module name="MemberName"><property name="format" value="^[a-z][a-z0-9]?[a-zA-Z0-9]*$"/><message key="name.invalidPattern"value="Member name ''{0}'' must match pattern ''{1}''."/></module><module name="ParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="LambdaParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="CatchParameterName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Catch parameter name ''{0}'' must match pattern ''{1}''."/></module><module name="LocalVariableName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Local variable name ''{0}'' must match pattern ''{1}''."/></module><module name="PatternVariableName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/><message key="name.invalidPattern"value="Pattern variable name ''{0}'' must match pattern ''{1}''."/></module><module name="ClassTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Class type name ''{0}'' must match pattern ''{1}''."/></module><module name="RecordComponentName"><property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" /><message key="name.invalidPattern" value="Record component name ''{0}'' must match pattern ''{1}''." /></module><module name="RecordTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Record type name ''{0}'' must match pattern ''{1}''."/></module><module name="RecordTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Record type name ''{0}'' must match pattern ''{1}''."/></module><module name="MethodTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Method type name ''{0}'' must match pattern ''{1}''."/></module><module name="InterfaceTypeParameterName"><property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/><message key="name.invalidPattern"value="Interface type name ''{0}'' must match pattern ''{1}''."/></module><module name="Indentation"><property name="basicOffset" value="4"/><property name="braceAdjustment" value="0"/><property name="caseIndent" value="4"/><property name="throwsIndent" value="2"/><property name="lineWrappingIndentation" value="4"/><property name="arrayInitIndent" value="8"/></module><module name="AbbreviationAsWordInName"><property name="ignoreFinal" value="false"/><property name="allowedAbbreviationLength" value="0"/><property name="allowedAbbreviations"value="XML, URL, ID, FTP, DTO, VO, DO, TO, PO, BO, POJO, HTTP, IP, IE"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,RECORD_COMPONENT_DEF"/></module><module name="NoWhitespaceBefore"><property name="tokens"value="COMMA, SEMI, POST_INC, POST_DEC, DOT,LABELED_STAT, METHOD_REF"/><property name="allowLineBreaks" value="true"/></module><module name="ParenPad"><property name="tokens"value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,RECORD_DEF"/></module><module name="AnnotationLocation"><property name="id" value="AnnotationLocationMostCases"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,RECORD_DEF, COMPACT_CTOR_DEF"/></module><module name="AnnotationLocation"><property name="id" value="AnnotationLocationVariables"/><property name="tokens" value="VARIABLE_DEF"/><property name="allowSamelineMultipleAnnotations" value="true"/></module><module name="NonEmptyAtclauseDescription"/><module name="InvalidJavadocPosition"/><module name="JavadocTagContinuationIndentation"><property name="offset" value="0"/></module><module name="AtclauseOrder"><property name="tagOrder" value="@param, @return, @throws, @deprecated"/><property name="target"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/></module><module name="JavadocMethod"><property name="accessModifiers" value="public"/><property name="allowMissingParamTags" value="true"/><property name="allowMissingReturnTag" value="true"/><property name="allowedAnnotations" value="Override, Test"/><property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/></module><module name="MissingJavadocType"><property name="scope" value="protected"/><property name="tokens"value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,RECORD_DEF, ANNOTATION_DEF"/><property name="excludeScope" value="nothing"/></module><module name="MethodName"><property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/><message key="name.invalidPattern"value="Method name ''{0}'' must match pattern ''{1}''."/></module><module name="EmptyCatchBlock"><property name="exceptionVariableName" value="ignore"/></module><module name="CommentsIndentation"><property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/></module><module name="SuppressionXpathFilter"><property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"default="checkstyle-xpath-suppressions.xml"/><property name="optional" value="true"/></module><module name="SuppressWarningsHolder"/><module name="SuppressionCommentFilter"><property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/><property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/><property name="checkFormat" value="$1"/></module><module name="SuppressWithNearbyCommentFilter"><property name="commentFormat" value="CHECKSTYLE.SUPPRESS\: ([\w\|]+)"/><property name="checkFormat" value="$1"/><property name="influenceFormat" value="1"/></module><!--IMPORT CHECKS--><module name="RedundantImport"><!-- Checks for redundant import statements. --><property name="severity" value="error"/><message key="import.redundancy"value="Redundant import {0}."/></module><module name="AvoidStarImport"><property name="severity" value="error"/></module><module name="RedundantModifier"><!-- Checks for redundant modifiers on various symbol definitions.See: http://checkstyle.sourceforge.net/config_modifier.html#RedundantModifier--><property name="tokens" value="METHOD_DEF, VARIABLE_DEF, ANNOTATION_FIELD_DEF, INTERFACE_DEF, CLASS_DEF, ENUM_DEF"/></module><module name="UnusedImports"><property name="severity" value="error"/><property name="processJavadoc" value="true"/><message key="import.unused"value="Unused import: {0}."/></module><!--WHITESPACE CHECKS--><module name="WhitespaceAround"><!-- Checks that various tokens are surrounded by whitespace.This includes most binary operators and keywords followedby regular or curly braces.--><property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/><property name="severity" value="error"/></module><module name="WhitespaceAfter"><!-- Checks that commas, semicolons and typecasts are followed bywhitespace.--><property name="tokens" value="COMMA, SEMI, TYPECAST"/></module><module name="NoWhitespaceAfter"><!-- Checks that there is no whitespace after various unary operators.Linebreaks are allowed.--><property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,UNARY_PLUS"/><property name="allowLineBreaks" value="true"/><property name="severity" value="error"/></module><module name="NoWhitespaceBefore"><!-- Checks that there is no whitespace before various unary operators.Linebreaks are allowed.--><property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/><property name="allowLineBreaks" value="true"/><property name="severity" value="error"/></module><module name="OperatorWrap"><!-- Checks that operators like + and ? appear at newlines rather thanat the end of the previous line.--><property name="option" value="NL"/><property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL,GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD,NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/></module><module name="OperatorWrap"><!-- Checks that assignment operators are at the end of the line. --><property name="option" value="eol"/><property name="tokens" value="ASSIGN"/></module><module name="ParenPad"><!-- Checks that there is no whitespace before close parens or afteropen parens.--><property name="severity" value="error"/></module><module name="ModifierOrder"/></module>
</module>

suppressions.xml

在项目根目录创建文件script/checkstyle/suppressions.xml

<?xml version="1.0"?>
<!--Licensed to the Apache Software Foundation (ASF) under oneor more contributor license agreements.  See the NOTICE filedistributed with this work for additional informationregarding copyright ownership.  The ASF licenses this fileto you under the Apache License, Version 2.0 (the"License"); you may not use this file except in compliancewith the License.  You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing,software distributed under the License is distributed on an"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.  See the License for thespecific language governing permissions and limitationsunder the License.-->
<!DOCTYPE suppressions PUBLIC"-//Puppy Crawl//DTD Suppressions 1.1//EN""http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"><suppressions><suppress checks="JavadocPackage" files=".*[\\/]src[\\/]test[\\/].*"/><suppress checks="JavadocPackage" files=".*[\\/]maven-archetypes[\\/].*"/><suppress checks="JavadocPackage" files=".*[\\/]examples[\\/].*"/><!-- suppress javadoc check for impl classes and package-info.java --><suppress checks="JavadocType" files=".*Impl\.java$" /><suppress checks="JavadocStyle" files=".+[\\/]package-info\.java$" /><!-- suppress all checks in the generated directories --><suppress checks=".*" files=".+[\\/]generated[\\/].+\.java"/><suppress checks=".*" files=".+[\\/]generated-sources[\\/].+\.java"/><suppress checks=".*" files=".+[\\/]generated-test-sources[\\/].+\.java"/><!-- suppress most all checks expect below--><suppress checks="^(?!.*(UnusedImports|IllegalImport)).*$" files=".*[\\/]src[\\/]test[\\/].*"/>
</suppressions>

pom.xml

<build><plugins><plugin><groupId>com.diffplug.spotless</groupId><artifactId>spotless-maven-plugin</artifactId><version>2.29.0</version><configuration><skip>false</skip><java><googleJavaFormat><version>1.7</version><style>AOSP</style></googleJavaFormat><removeUnusedImports /><formatAnnotations /><importOrder><order>wiki.hadoop,org.apache,org,com,cn,,javax,java,\#</order></importOrder><replaceRegex><name>Remove wildcard imports</name><searchRegex>import\s+(static)*\s*[^\*\s]+\*;(\r\n|\r|\n)</searchRegex><replacement>$1</replacement></replaceRegex></java><pom><sortPom><encoding>UTF-8</encoding><nrOfIndentSpace>4</nrOfIndentSpace><keepBlankLines>true</keepBlankLines><indentBlankLines>false</indentBlankLines><indentSchemaLocation>true</indentSchemaLocation><spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement><sortModules>false</sortModules><sortExecutions>false</sortExecutions><predefinedSortOrder>custom_1</predefinedSortOrder><expandEmptyElements>false</expandEmptyElements><sortProperties>false</sortProperties></sortPom><replace><name>Leading blank line</name><search>project</search><replacement>project</replacement></replace></pom><markdown><includes><include>docs/**/*.md</include></includes><flexmark /></markdown><upToDateChecking><enabled>true</enabled></upToDateChecking></configuration><executions><execution><id>spotless-check</id><goals><goal>check</goal></goals><phase>validate</phase></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-checkstyle-plugin</artifactId><version>3.3.0</version><configuration><configLocation>./script/checkstyle/checkstyle.xml</configLocation><suppressionsLocation>./script/checkstyle/suppressions.xml</suppressionsLocation><includeTestSourceDirectory>true</includeTestSourceDirectory><consoleOutput>true</consoleOutput><failsOnError>true</failsOnError><linkXRef>false</linkXRef></configuration><executions><execution><id>validate</id><phase>validate</phase><goals><goal>check</goal></goals></execution></executions></plugin></plugins></build>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/41606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis学习(005 java客户端 RedisTemplate学习)

黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第16p-第p23的内容 文章目录 java客户端jedisSpringDataRedis项目实现hash哈希操作 java客户端 jedis 测试 ps:如果连接不上&…

vs2019 无法打开项目文件

vs2019 无法打开项目文件&#xff0c;无法找到 .NET SDK。请检查确保已安装此项且 global.json 中指定的版本(如有)与所安装的版本相匹配 原因&#xff1a;缺少组件 解决方案&#xff1a;选择需要的组件进行安装完成

步进电机改伺服电机

步进电机&#xff1a; 42&#xff1a;轴径5mm 57&#xff1a;轴径8mm 86&#xff1a;轴径14mm 【86CME120闭环】// 12牛米 伺服电机&#xff1a; 40&#xff1a; 60&#xff1a; 80&#xff1a; 86&#xff1a; ECMA——C 1 0910 R S 4.25A 轴径…

评价ChatGPT与强人工智能的未来

在人工智能领域&#xff0c;ChatGPT的出现无疑是一个里程碑事件。它不仅展示了自然语言处理技术的巨大进步&#xff0c;也引发了人们对于强人工智能&#xff08;AGI&#xff09;的无限遐想。本文将从多个角度评价ChatGPT&#xff0c;并探讨强人工智能距离我们还有多远。 ChatGP…

无人机运营合格证及无人机驾驶员合格证(AOPA)技术详解

无人机运营合格证及无人机驾驶员合格证&#xff08;AOPA&#xff09;技术详解如下&#xff1a; 一、无人机运营合格证 无人机运营合格证是无人机运营企业或个人必须获得的证书&#xff0c;以确保无人机在运营过程中符合相关法规和标准。对于无人机运营合格证的具体要求和申请…

无人机人员搜救

人员搜救-水域救援 水域搜救&#xff1a;快速水面搜查 物资抛投&#xff1a;救生物资抛投 绳索牵引&#xff1a;牵引救援绳索 领航船艇&#xff1a;水面侦察领航 人员搜救 昼夜搜救&#xff0c;精准定位 水域搜救 经纬 M300 RTK 搭载禅思 H20T 能够满足全天候作业需求&a…

新手教学系列——Git Stash踩坑

在之前的文章《如何彻底避免Git代码相互覆盖问题》中,我曾介绍过通过规范分支合并和使用git stash来避免代码覆盖问题。今天,我要深入探讨一下git stash的使用,并分享一些使用过程中遇到的坑,希望能帮你避免类似问题。 脚本mg.sh简介 为了更好地管理代码合并,我编写了一…

linux之管道重定向

管道与重定向 一、重定向 将原输出结果存储到其他位置的过程 标准输入、标准正确输出、标准错误输出 ​ 进程在运行的过程中根据需要会打开多个文件&#xff0c;每打开一个文件会有一个数字标识。这个标识叫文件描述符。 进程使用文件描述符来管理打开的文件&#xff08;FD--…

windows USB 设备驱动开发-控制传输的数据包

每次在主机控制器和 USB 设备之间移动数据时&#xff0c;都会发生传输。 通常&#xff0c;USB 传输可大致分为控制传输和数据传输。 所有 USB 设备都必须支持控制传输&#xff0c;并且可以支持用于数据传输的端点。 每种类型的传输都与设备缓冲区USB 端点 的类型相关联。 控制传…

泛微开发修炼之旅--32ecology对接海康威视综合安防管理系统,人脸识别机器数据同步代码方案及源码

文章链接&#xff1a;32ecology对接海康威视综合安防管理系统&#xff0c;人脸识别机器数据同步代码方案及源码

Open3D 在点云中构建八叉树

目录 一、概述 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2构建后点云 一、概述 八叉树&#xff08;Octree&#xff09;是一种树状数据结构&#xff0c;用于递归地将3D空间分割成较小的立方体。八叉树特别适用于3D计算机图形学、点云处理和空间…

[图解]企业应用架构模式2024新译本讲解22-标识映射

1 00:00:01,080 --> 00:00:04,710 我们来看一下标识映射这个模式 2 00:00:08,030 --> 00:00:10,110 它是属于对象-关系 3 00:00:10,120 --> 00:00:11,150 行为模式 4 00:00:11,160 --> 00:00:13,890 就是说&#xff0c;在动态的时候 5 00:00:15,770 --> 00:…

C# Application.DoEvents()的作用

文章目录 1、详解 Application.DoEvents()2、示例处理用户事件响应系统事件控制台输出游戏和多媒体应用与操作系统的交互 3、注意事项总结 Application.DoEvents() 是 .NET 框架中的一个方法&#xff0c;它主要用于处理消息队列中的事件。在 Windows 应用程序中&#xff0c;当一…

实验四 图像增强—灰度变换之直方图变换

一&#xff0e;实验目的 1&#xff0e;掌握灰度直方图的概念及其计算方法&#xff1b; 2&#xff0e;熟练掌握直方图均衡化计算过程&#xff1b;了解直方图规定化的计算过程&#xff1b; 3&#xff0e;了解色彩直方图的概念和计算方法 二&#xff0e;实验内容&#xff1a; …

课设:选课管理系统(Java+MySQL)

在本博客中&#xff0c;我将介绍用Java、MySQL、JDBC和Swing GUI开发一个简单的选课管理系统。 技术栈 Java&#xff1a;用于编写应用程序逻辑MySQL&#xff1a;用于存储和管理数据JDBC&#xff1a;用于连接Java应用程序和MySQL数据库Swing GUI&#xff1a;用于构建桌面应用程…

555 定时器芯片工作原理

在本教程中&#xff0c;您将学习如何使用 555 定时器做一些有趣的事情。许多人用它做的第一件事就是制造闪烁的灯光。但这只是用该芯片可以做很多事情的简单示例之一。您还可以控制电机、创建闹钟、创建乐器等等。 让我们先来概览一下这些引脚。 555 定时器引脚排列 引脚 1 接地…

【SpringCloud】概述 -- 微服务入门

在Java的整个学习过程中&#xff0c;大家势必会听见一些什么分布式-微服务、高并发、高可用这些专业术语&#xff0c;给人的感觉很高级&#xff0c;有一种高深莫测的感觉。可以看一下这篇博客对这些技术架构的演变有一个初步的认识: 服务端⾼并发分布式结构演进之路-CSDN博客文…

image媒体组件属性配合swiper轮播

图片组件&#xff08;image&#xff09; 先插入个图片试试&#xff0c;插入图片用src属性&#xff0c;这是图片&#xff1a; 代码如下&#xff1a; <template><view><swiper indicator-dots indicator-color "#126bae" indicator-active-color &…

CobaltStrike的内网安全

1.上线机器的Beacon的常用命令 2.信息收集和网站克隆 3.钓鱼邮件 4.CS传递会话到MSF 5.MSF会话传递到CS 1上线机器的Beacon的常用命令 介绍&#xff1a;CobaltStrike分为服务端和客户端&#xff0c;一般我们将服务端放在kali&#xff0c;客户端可以在物理机上面&#xff0…

tongweb 部署软航流版签一体化应用示例 提示跨域错误CORS ERROR

目录 问题现象与描述 解决办法 原理解析 什么是CORS 浏览器跨域请求限制 跨域问题解决方法 跨域请求流程 浏览器请求分类解析 http请求方法简介 问题现象与描述 重庆软航科技有限公司提供了一套针对针对word、excel等流式文件转换成PDF版式文件并进行版式文件在线签章…