maven进阶——开发自定义插件

Maven 插件列表详解 Maven 是一个强大的项目管理和构建工具,广泛应用于 Java 项目中。作为一款优秀的构建管理工具,Maven 不仅提供了标准化的项目结构和依赖管理,还通过其丰富的插件系统,极大地扩展了其功能和灵活性。无论是代码编译、测试、打包,还是部署、报告生成,Maven 插件都扮演着不可或缺的角色。 本文将深入探讨 Maven 的插件体系,详细介绍各类插件的用途、主要目标和适用的生命周期阶段。内容涵盖了 Maven 官方插件、被淘汰的插件、社区驱动的 MojoHaus 插件、国内外企业开发的非官方插件以及如何自定 阅读详情
前言

maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对各位读者有所帮助。

知识背景

什么是maven插件?
讲如何开发maven插件之前,不妨先来聊一下什么是maven的插件。

我们知道,maven中主要有三大生命周期,clean,default和report,不同的生命周期中提供了一些快捷的操作命令给开发人员去进行项目的清理、编译、打包等操作。之所以我们可以通过类似于mvn clean compile等命令快速完成项目的清理和构建,实际上是因为maven在项目核心的生命周期节点上,已经设置好了默认的运行插件,我们执行命令的时候,实际上调用的就是绑定对应生命周期的插件。
maven插件本质上就是一个jar包,不同的插件里面有着不同功能的代码,当我们调用该插件的时候,其实就是通过执行jar包中的方法,去达到对应的goal,实现我们的目的。除了官网的maven插件之外,其实maven还允许我们根据实际的项目需要,自定义去开发maven插件,从而满足我们的项目构建需要。

关于maven的生命周期和插件,我们可以从官方文档中了解更多信息:
maven的生命周期:https://maven.apache.org/ref/3.8.6/maven-core/lifecycles.html
maven生命周期绑定的默认插件:https://maven.apache.org/ref/3.8.6/maven-core/default-bindings.html

一、自定义插件demo开发
(一)开发自定义插件
步骤一:配置pom文件

我们先在idea中创建一个maven项目,并在pom文件中写入如下配置,这里的目的是标识我们这个项目是maven插件项目,需要按照插件的方式来进行打包。

<packaging>maven-plugin</packaging>

其次,引入插件开发所需要的依赖,这里版本不一定需要和我一致,只要两个依赖之前版本不要差距过大就行。

         <!--这个依赖引入了插件开发需要的相关基础类-->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.0</version>
        </dependency>
         <!--这个依赖引入了插件开发需要的相关注解-->
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
步骤二:定义插件类

我们上一个步骤已经在pom文件中定义了我们这个项目是一个maven插件类型的项目,而maven插件是需要对外提供各种实际应用能力的,在这个步骤中,我们将定义我们这个插件对外提供的实际能力,这样其他项目想要使用我们插件的时候,就可以选择对应的goal来执行了。
PS:需要注意的是,一个插件是可以同时提供多种能力的,但本案例只作为演示所以只会写一个功能作

1、定义插件类的2种方式

定义插件类有2种方式,第一种是创建java类,实现org.apache.maven.plugin.Mojo接口。

void execute() throws MojoExecutionException, MojoFailureException;
void setLog( Log log );
Log getLog();

这个接口一共定义了三个接口方法:

  • execute 这个方法为核心方法,当使用mvn命令调用插件的目标的时候,最后具体调用的就是这个方法
  • setLog:注入一个标准的Maven日志记录器,允许这个Mojo向用户传递事件和反馈
  • getLog:获取注入的日志记录器

一般来说,我们并不会直接通过实现接口的方式来定义插件,而是会采用继承maven提供的抽象类org.apache.maven.plugin.AbstractMojo来定义我们的插件类。

public abstract class AbstractMojo implements Mojo, ContextEnabled {
         ...
}

我们可以看到,这个抽象类实现了Mojo接口,同时这个抽象类还实现了setLog和getLog方法,只留下execute方法给开发人员去实现。这个类中Log默认可以向控制台输出日志信息,maven中自带的插件都继承这个类,一般情况下我们开发插件目标可以直接继承这个类,然后实现execute方法就可以了。

2、在我们的代码中进行实操

在刚刚创建的插件项目中,创建一个普通的java类,继承org.apache.maven.plugin.AbstractMojo这个抽象类,同时需要在类上面使用@Mojo注解。这样maven在执行我们的插件的时候,才能够找到我们的入口类。

在execute方法中,我们简单地打印一句话到控制台

@Mojo(name = "TimerPlugin")
public class TimerPlugin extends AbstractMojo {

    public void execute() throws MojoExecutionException, MojoFailureException {
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        getLog().info("timer plugin is running,current time is " + currentTime);
    }
}
步骤三:将我们的插件上传到我们的本地仓库

执行如下maven命令实现插件的上传,打包完成后我们就可以在我们本地仓库中找到我们的插件了。

mvn clean install

(二)验证插件

插件开发成功后,我们可以有2种方式来使用我们的自定义插件

方式一:直接通过maven命令(我们在第三章中会详细讲一下这个maven命令的使用)

maven命令的格式如下:

mvn 插件groupId:插件artifactId[:插件版本]:插件目标名称

对应我们的案例,执行的命令即为mvn com.qiqv:timer-plugin-demo:TimerPlugin,执行命令后可以看到控制台中就已经出现了我们插件中打印的语句。

方式二:把自定义插件绑定在项目的生命周期中

如果我们的自定义插件是希望在打包的过程某个固定的生命周期发生作用,那么我们可以在pom文件中把插件绑定在我们项目的生命周期中。

插件写在build->plugins->plugin标签下,groupId这些信息和插件保持一直,然后需要在executions标签中定义我们这个使用这个自定义插件的哪个能力,也就是goal,phase标签里面定义要绑定的生命周期,id用于命令,可以自己定义。

    <build>
        <plugins>
            <plugin>
                <groupId>com.qiqv</groupId>
                <artifactId>timer-plugin-demo</artifactId>
                <version>1.0.0</version>
                <executions>
                    <execution>
                        <id>test</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>TimerPlugin</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

在外部项目中绑定好插件后,我们通过mvn compile命令看一下结果

我们可以看到,我们的自定义插件顺利随着compile生命周期执行了。

二、插件传参

在第一章中,我们已经简单实现了一个maven插件,但实际上这种没有任何参数的插件一般来说很难支持比较复杂、灵活的功能。所以这一章中,我们将学习如何把参数传递给我们的插件。

(一)在Mojo类中定义我们接收数据的参数

延续第一章的例子,我们在插件类中定义2个变量,并加上@Paramter注解,这个注解将变量标识为mojo参数。注解的defaultValue参数定义变量的默认值。property参数可用于通过引用用户通过-D选项设置的系统属性,即通过从命令行配置mojo参数,如mvn ... -Dtimer.username=moutoryJava可以将moutory的值传递给userName参数。

当然了,如果说不打算通过命令行执行,只想传参给和生命周期绑定的插件,那么也需要要加上注解,注解里面可以不用配置其他属性。

@Mojo(name = "TimerPlugin")
public class TimerPlugin extends AbstractMojo {

    @Parameter(property = "timer.username" ,defaultValue = "moutory")
    private String userName;

    @Parameter(property = "timer.status", defaultValue = "happy")
    private String status;

    public void execute() throws MojoExecutionException, MojoFailureException {
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        getLog().info("timer plugin is running, current time is " + currentTime);
        getLog().info(String.format("hi %s ! Now you are %s",userName,status));
    }
}
(二)在使用中向我们的插件传递参数
方式一:在pom文件进行定义

这种做法一般是用于和生命周期绑定使用的插件,我们可以在配置插件的时候,利用configuration标签来配置我们插件的值。configuration标签内可以写入我们想要配置的参数,标签的key为我们插件定义的属性名,标签的value为我们想要配置的值。

以下面的配置为例,我们分别为userName和status配置不同的值:

 <build>
        <plugins>
            <plugin>
                <groupId>com.qiqv</groupId>
                <artifactId>timer-plugin-demo</artifactId>
                <version>1.0.0</version>
                <executions>
                    <execution>
                        <id>test</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>TimerPlugin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <userName>Jim</userName>
                    <status>good</status>
                </configuration>
            </plugin>
        </plugins>
    </build>

使用mvn compile命令,看一下执行的结果

方式二:maven命令传参

这种方式比较适用于那些独立使用的插件,比如代码扫描工具或者依赖扫描插件。使用maven命令传参也十分简单,在命令后面使用-Dkey=value。这里的key为@property中配置的property属性的值,value为我们实际传入的值。对应到我们上面的案例,这里的参数就可以是-Dtimer.username=Tonny -Dtimer.status=bad。

使用maven命令传参

(二)插件中可以接收的参数类型

除了String类型,自定义插件还可以接收其他多种参数类型,下面就对这些参数进行简单的介绍。

1、boolean类型

@Parameter
private boolean myBoolean;

<configuration>
      <myBoolean>true</myBoolean>
</configuration>
2、数字类型

数字类型包含:byte, Byte, int, Integer, long, Long, short, Short,读取配置时,XML文件中的文本将使用适当类的integer.parseInt()或valueOf()方法转换为整数值,这意味着字符串必须是有效的十进制整数值,仅由数字0到9组成,前面有一个可选的-表示负值。

@Parameter
private Integer myNum;

<configuration>
      <myNum>2</myNum>
</configuration>
3、File类型参数

读取配置时,XML文件中的文本用作所需文件或目录的路径。如果路径是相对的(不是以/或C:之类的驱动器号开头),则路径是相对于包含POM的目录的

@Parameter
private File myFile;

<configuration>
      <myFile>C:\test</myFile>
</configuration>
4、枚举类型参数

public enum Color {
      GREEN,
      RED,
      BLUE
}
/**
* My Enum
*/
@Parameter
private Color myColor;
<myColor>GREEN</myColor>
5、数组类型参数
@Parameter
private String[] myArr;
<configuration>
      <myArr>
           <param>aa</param>
           <param>bb</param>
     </myArr>
</configuration>
6、Collections类型参数

和数组类型参数用法一样

7、Maps类型参数

@Parameter
private Map myMap;

<configuration>
   <myMap>
         <key1>value1</key1>
        <key2>value2</key2>
   </myMap>
</configuration>
8、Properties类型参数

@Parameter
private Properties myProperties;

<myProperties>
  <property>
    <name>propertyName1</name>
    <value>propertyValue1</value>
  <property>
  <property>
    <name>propertyName2</name>
    <value>propertyValue2</value>
  <property>
</myProperties>
9、自定义类型参数

@Parameter
private MyObject myObject;
<myObject>
  <myField>test</myField>
</myObject>
三、自定义插件前缀的使用

理论上我们开发自定义插件时,artifactId是可以随便写,并没有严格的书写规定。但即使把artifactId定义得比较短,我们在通过命令使用插件时,还是不得不敲上一长串的命令,无法像mvn clean这些官方插件一样,使用很简单的命令就可以完成操作。出于简化命令的目的,其实maven官方已经定义一套插件命名规范,只要满足这套命名规范,就可以在执行命令的时候简化我们的语法。

若自定义插件的artifactId满足下面的格式:

xxx-maven-plugin

如果采用这种格式的maven会自动将xxx指定为插件的前缀,其他格式也可以,不过此处我们只说这种格式,这个是最常用的格式。

比如我们上面自定义插件改为timer-maven-plugin,他的前缀就是timer。
当我们配置了插件前缀,可以插件前缀来调用插件的目标了,命令如下:

mvn 插件前缀:插件目标

但是上面的命令支提供了插件前缀,那么maven是如何知道对应的groupId的呢?

maven默认会在仓库"org.apache.maven.plugins" 和 "org.codehaus.mojo"2个位置查找插件,比如:
mvn clean:help。这个是调用maven-clean-plugin插件的help目标,maven-clean-plugin的前缀就是clean,他的groupId是org.apache.maven.plugins,所以能够直接找到。

但是我们自己定义的插件,如果也让maven能够找到,需要下面的配置:
在~/.m2/settings.xml中配置自定义插件组,我们需要在pluginGroups中加入自定义的插件组groupId,如:

<pluginGroup>com.qiqv</pluginGroup>

这样当我们通过前缀调用插件的时候,maven除了会在2个默认的组中查找,还会在这些自定义的插件组中找,一般情况下我们自定义的插件通常使用同样的groupId。
当我们配置了上面的自定义插件组后,我们就可以改为用下面的命令来调用我们的自定义插件了。

mvn timer:TimerPlugin

使用简化命令调用我们的插件

通过上面这种方式,我们就可以实现用简化命令来调用我们的插件啦~~下面是需要额外注意的事项:
1、官方的插件命名一般是maven-xxx-plugin,第三方的自定义插件命名一般是xxx-maven-plugin,我们的命名规范尽量不要和官方插件的一致。
2、如果不想配置settings.xml这么麻烦,也可以直接在命令中加上groupId,这样也可以让maven可以找到你的自定义插件。

四、开发一个功能性更强的自定义组件

通过前面三章的介绍,其实我们已经能够掌握自定义插件开发的大部分知识了,接下来我们就以开发功能性更强的插件为例,来作为收尾的一个小案例。
对一些web项目来说,打包完之后我们需要把war包部署到tomcat上面进行部署,每次都需要手动复制包十分的麻烦,我们不妨尝试着自己开发一个插件,来解决这个场景的问题。
(当然了,现在idea都有这种自动部署的功能,但作为学习的案例,自己手动实现一下这个功能也是十分有意思的)

步骤一:创建一个新的插件项目,定义pom文件

这一步和之前的并没有什么区别,还是定义项目的打包类型以及相关依赖

<packaging>maven-plugin</packaging>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
步骤二:创建插件的核心执行类

这里的话没有写的很复杂,插件使用者提供一下war包位置,tomcat路径以及最终的文件名,插件做一下简单的IO而已。

@Mojo(name="deploy")
public class DeployPlugin extends AbstractMojo {
    @Parameter
    private String sourceWarPath;
    @Parameter
    private String tomcatHome;
    @Parameter
    private String targetFileName;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        this.getLog().info("deploy plugin starting...");
        this.getLog().info("sourceWarPath:[{"+sourceWarPath+"}] , tomcatHome:[{"+tomcatHome+"}]");
        boolean cpSuccess = this.deployFile(sourceWarPath, tomcatHome, targetFileName);
        if(cpSuccess){
            this.getLog().info("deploy success");
            return;
        }
        this.getLog().error("deploy fail");
    }

    private boolean deployFile(String sourceWarPath, String tomcatHome,String targetFileName) {
        if(StringUtils.isBlank(sourceWarPath) || StringUtils.isBlank(tomcatHome)){
            throw new RuntimeException("missing required param!");
        }
        InputStream inputS = null;
        OutputStream outputS = null;
        String targetWarPath = tomcatHome + File.separator +"webapps"  + File.separator + targetFileName;

        // 通过 String 创建文件
        try{
            File destF = new File(targetWarPath);
            File srcF = new File(sourceWarPath);

            // 通过 File 创建 文件流
            inputS = new FileInputStream(srcF);
            outputS = new FileOutputStream(destF);

            // 读写流
            byte[] buffer = new byte[1024];
            int length = 0;
            while ((length = inputS.read(buffer)) > 0) {
                outputS.write(buffer, 0, length);
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }finally {
            closeIO(inputS,outputS);
        }
        return true;
    }

    private void closeIO(InputStream inputS, OutputStream outputS) {
        // 关闭流
        if(inputS != null){
            try{
                inputS.close();
            }catch (Exception e){
                this.getLog().error("close input stream fail..");
                e.printStackTrace();
            }
        }
        if(outputS != null){
            try{
                outputS.close();
            }catch (Exception e){
                this.getLog().error("close output stream fail..");
                e.printStackTrace();
            }
        }
    }
}

步骤三:在我们的其他项目引入我们的插件

这里需要注意,除了需要传参之外,还需要把插件绑定在package的生命周期

    <build>
        <plugins>
            <plugin>
                <groupId>com.qiqv</groupId>
                <artifactId>webDeploy-maven-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <executions>
                    <execution>
                        <id>test</id>
                        <phase>package</phase>
                        <goals>
                            <goal>deploy</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sourceWarPath>D:\devWorkPlace\devCode\mime\maven-plugin\order-api\target\order-api-1.0-SNAPSHOT.war</sourceWarPath>
                    <tomcatHome>D:\devWorkPlace\devTool\apache-tomcat-9.0.68</tomcatHome>
                    <targetFileName>order-api-1.0-SNAPSHOT.war</targetFileName>
                </configuration>
            </plugin>
        </plugins>
    </build>
步骤四:项目打包,观察插件的运行日志:
mvn package

插件执行日志

从日志上面来看,war包已经复制成功了,那么切换到对应的webapp目录上面,也可以看到,war包确实已经复制过来了。

执行效果图

总结

这篇文章我们对maven自定义插件的开发方法进行了介绍,了解插件的参数如何传递以及不同的参数如何传递,并配合两个简单的案例来进行讲解。总的来说,自定义插件的开发并不复杂,掌握了基本知识后,难度其实在于插件所要实现的具体功能,后期有时间了我们可以出一期文章来分析某些优秀的开源maven插件是怎么实现的。

本篇文章的源码,可以从我的gitee上面获取,地址如下:https://gitee.com/moutory/maven-plugin-demo
最后,也要十分感谢参考文章中的作者,他详尽的文章给了我很大的帮助,也十分推荐各位读者去看看这篇文章。

参考文章:

自定义插件,Maven的生命交给你来设计

Maven 插件自定义开发 如果需要在其他项目中使用我们自定义的 Maven 插件,则只需要创建一个 Maven 项目,在 Maven 项目的 pom.xml 文件中引入如下配置即可。这里,我直接跳过了 Maven 项目的创建,相信小伙伴们都会创建 Maven 项目,这里,我就不再赘述了,直接给出 pom.xml 文件的配置,如下所示。这里,我们先来说说自定义 Maven 插件的步骤,这里,我将自定义 Maven 插件的步骤总结如下。除了通过配置的方式使用插件以外,Maven 也提供了通过命令直接调用插件目标其命令格式如下所示。 阅读详情

相关推荐

Java 中 Maven 的插件的自定义开发流程

本文旨在为Java开发者提供一份全面的Maven插件开发指南,涵盖从基础概念到高级应用的所有关键环节。理解Maven插件的工作原理和架构掌握自定义Maven插件的开发流程学会如何打包、测试和部署自定义插件了解插件开发中的最佳实践和常见陷阱本文范围包括Maven 3.x版本的插件开发,重点介绍核心概念和实际开发技巧。背景介绍:建立基本认知框架核心概念:深入理解Maven插件架构开发流程:分步详解插件开发步骤实战案例:通过完整示例巩固知识应用扩展:探讨高级应用场景和技巧Mojo。

AI开发架构师 1068

Maven插件开发

Maven插件开发

飞鸟Blog 2671

自定义基于maven插件的代码生成器

目录前言具体实现1. pom.xml2. MoJo的代码3. controller模板遇到的问题1. install出错2. 执行插件目标generator命令报错3. 生成的dao层文件执行insert语句报错使用插件1. pom.xml文件2. generator.properties3. 执行命令 前言 最近研究了一下maven的自定义插件,之前用过maven中的mybatis-gener...

nb7474的博客 4710

Maven - 10、设计你自己的maven插件

maven中的插件是有很多目标(goal)组成的,开发插件,实际上就是去编写插件中目标的具体代码。execute:这个方法比较重要,目标的主要代码就在这个方法中实现,当使用mvn命令调用插件的目标的时候,最后具体调用的就是这个方法。setLog:注入一个标准的Maven日志记录器,允许这个Mojo向用户传递事件和反馈getLog:获取注入的日志记录器说一下上面这个Log,这是一日志接口,里面定义了很多方法,主要用户向交互者输出日志,比如我们运行mvn clean。

。 2万+

maven 自定义插件小示例

NULL 博文链接:https://fengyilin.iteye.com/blog/2389638

实战:如何通过修改VTS和HTS调整GC4653 sensor帧率(附完整计算步骤)

本文以GC4653图像传感器为例,详细解析了通过修改VTS和HTS寄存器来精确调整输出帧率的完整流程。文章深入剖析了帧率计算公式FPS = PCLK / (VTS × HTS)的核心原理,并提供了从获取寄存器参数、计算目标VTS值到系统验证的实战步骤,帮助工程师掌握独立优化Sensor性能、提升低照度画质的关键技能。

gin88的博客 338

Maven:自定义插件(插件开发)

Maven:自定义插件(插件开发)

程序员无羡的博客 1176

Unity IAP插件实战:从零搭建Google Play内购系统

本文详细介绍了如何使用Unity IAP插件从零搭建Google Play内购系统,涵盖环境准备、双端配置、核心API实现及常见问题排查。通过实战代码示例,帮助开发者快速掌握跨平台内购功能开发,提升手游商业化效率。

weixin_28692867的博客 430

maven学习巩固

maven学习巩固1.认识Maven2.特点3.下载4.新建一个Maven项目5.版本管理6.常用命令7.插件8.自定义插件 https://maven.apache.org/guides/plugin/guide-java-plugin-development.html9.Profile10.自定义插件11.自定义插件 1.认识Maven 2.特点 a)约定优于配置 b)简单 c)测试支持 d)...

zhipengliu的博客 255

SAP PP实战:MRP Area怎么用?手把手教你按产线、委外供应商拆分物料计划

本文详细解析了SAP PP模块中MRP Area的功能与应用,指导如何按产线、委外供应商拆分物料计划,实现精细化物料需求管理。通过实战案例展示MRP Area在减少计划冲突、提升库存准确率方面的显著效果,为制造业企业提供可落地的解决方案。

weixin_27015733的博客 432

自动驾驶仿真 (三)—— 基于PreScan与Simulink的AEB系统仿真

自动驾驶仿真三—— 基于PreScan&Simulink的AEB系统仿真1. AEB自动紧急制动系统1. 1 TTC碰撞时间模型1. 2 C-NCAP法规部分术语与定义1. 3 主动安全ADAS系统试验项目2. AEB仿真分析建模2.1 搭建场景2.2 传感器建模2.3 添加AEB控制系统3. 典型工况仿真3.1 CCRs仿真测试3.1 CCRm仿真测试4. 参考学习的书目教材 博主前面的博文已经介绍了Prescan&Simulink基本的场景建模及仿真分析流程,《自动驾驶仿真 (二)——

zhudj08的博客 1万+

面试官:开发过Maven插件吗?我:开发过啊。。,2024年最新编译器面试题

面试题文档来啦,内容很多,485页!由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

2401_84436997的博客 972

ADT MCP Server 把 ABAP 开发带进 Agent 模式

今天讨论 ADT MCP Server,不能只把它看成 Visual Studio Code 里多出来的一个开关。它真正有意思的地方,在于它把 ABAP 后端开发里那些原本需要手工点击、手工创建、手工激活、手工查服务元数据的动作,包装成一组可以被 GitHub Copilot 这类 coding agent 调用的工具。SAP 在 RAP130 练习里把它描述为运行在 ADT for Visual Studio Code 扩展内部的本地 HTTP Server,它实现的是 Model Context Pro

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 181

gradle7.0 打包插件发布到本地maven仓库

gradle

liuqinhou的博客 4488

YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点

本文给大家带来的改进机制是BiFPN双向特征金字塔网络,其是一种特征融合层的结构,也就是我们本文改进YOLOv11模型中的Neck部分,它的主要思想是通过多层级的特征金字塔和双向信息传递来提高精度。本文给大家带来的结构可以让大家自行调节网络结构大小,同时能够达到一定的轻量化效果,为什么发BiFPN呢因为它算是YOLO系列改进中的常青树了,大家可以借鉴它的双向特征思想来创新自己的Neck结构本文的BiFPN通过yaml文件配置可以让大家自行调配其结构。

Snu77的博客 9094

8.19华为OD机试真题 新系统 - 基站低能耗时段统计 (Java/Py/C/C++/Js/Go)

8.19华为OD机试真题 新系统 - 基站低能耗时段统计 (Java/Py/C/C++/Js/Go)

算法大师! 1137

自定义maven插件 开发步骤手册

Maven只是一套框架,它的功能基于全部依赖于插件来实现。因此可以通过插件开发来定制Maven。

张紫娃的博客 3635

【Unity】【Pico】【VR开发】为何PICO打包后真机运行闪退

由于并没有开版权验证,而且闪退后也并没有弹框说版权问题,所以还是怀疑环境有什么地方不对。设置步骤,项目配置都没问题,Build也成功,Unity版本是符合要求的2022LTS版本,但是一在真机上运行就闪退。

每日出拳老爷子的博客 3174

Maven - 插件开发入门 自定义插件实现项目个性化构建

本文介绍了Maven插件开发的基础知识和实践方法。主要内容包括: Maven插件开发的需求场景:特定构建逻辑、代码生成、自定义报告等 Maven插件的两种类型:目标插件(Mojo)和生命周期插件 Maven插件开发的核心组件:插件描述文件、Mojo类、Mojo注解 标准Maven插件项目的目录结构 插件POM文件的详细配置说明,包括: 必须声明为maven-plugin打包类型 核心依赖maven-plugin-api和maven-plugin-annotations 使用maven-plugin-plug

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Maven插件开发教程

Maven是一个一个优秀的项目管理开源框架,其插件机制为其功能扩展提供了非常大的便捷性。大多数情况下,我们不需要自己开发Maven插件,因为Maven本身提供了很多便捷的官方插件。但是对于某些特殊场景和特殊需求,开发一个自定义的Maven插件能大大提高开发效率。本文以一个简单的例子,展示如何创建一个自定义的Maven插件。 Maven插件开发 本文会以一个自制的Maven插件为例,展示如何使用Idea从0开始构建自制的Maven插件。 Maven插件目标 Maven本质是一个插件执行框架,所有的工作都是通过

小明的博客 6629

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【Maven】自定义Maven插件

开发Maven插件。

m0_46308522的博客 1250

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

maven自定义插件开发

Maven 作为一个优秀的项目管理工具,其插件机制为其功能扩展提供了非常大的便捷性。虽然说大多数情况下,我们可能不太会自己去编写 Maven 插件,但不排除在某些特殊的情况下,我们需要去完成一个自己的插件,来协助我们处理某些比较通用的事情。正好,最近有一些需求可能需要对 Drools 的一个 Maven 插件进行扩展,所以学习一下 Maven 的插件编写。Maven 插件的命名规范一般来说,我们会将

u012620150的专栏 1万+

maven 自定义插件开发及使用

mave自定义插件 介绍 本文采用maven自定义插件实现了解决html引入css、js缓存的问题。问题解决思路为扫描路径下的html文件,并将html文件中引入的css、js路径后缀加入版本号的方案。如将https://code.jquery.com/jquery-3.2.1.slim.min.js变更为https://code.jquery.com/jquery-3.2.1.slim.mi...

yanmei_yaomy的专栏 1943

面试官:开发过Maven插件吗?我:开发过啊。。。

还不会Maven插件开发?看这一篇就够了!!

冰河的专栏 2765

Maven实战(六)- 开发自定义Maven插件

表示该目标是否必须在一个Maven项目中运行,默认为true。这里介绍一款插件maven-invoker-plugin,该插件能够用来在一组项目上执行Maven,并检查每个项目的构建是否成功,最后,它还可以执行BeanShell或者Groovy脚本来验证项目构建的输出。任何一个Mojo都必须使用该注解声明明自己的目标名称,有了目标定义之后,我们才能在项目中配置该插件目标,或者在命令行调用之。这是唯一必须声明的属性,当用户使用命令行调用插件,或者者在POM中配置插件的时候,都需要使用该目标名称。

AHAO的博客 3011

Maven第六章:Maven的自定义插件开发

maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对各位读者有所帮助。

RodJohnsonDoctor的专栏 1284
上一篇: Spring Web 数据脱敏
下一篇: Lock wait timeout exceeded; try restarting transaction问题分析
shadow_zed
博客等级 码龄10年 6289粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值