最近开发代码生成相关的工具使用了maven插件开发方式
1. 添加依赖
<!--maven插件必须的-->
<packaging>maven-plugin</packaging>
<!--maven plugin必须-->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.8.4</version>
<scope>provided</scope>
</dependency>
<!--maven plugin jdk5 之后支持注解-->
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.2</version>
<scope>provided</scope>
</dependency>
<!--插件版本用新的,老版本会报错-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.4</version>
</plugin>
注意packing
必须为maven-plugin
, artifactId
建议以maven-plugin
结尾
2. 代码示例
@Mojo(name = "sayhi", threadSafe = true)
public class HelloMojo extends AbstractMojo {
/**
* 参数定义
*/
@Parameter(property = "sayhi.greeting", defaultValue = "hello world")
private String greeting;
/**
* @parameter
*/
@Parameter(property = "outputDir", defaultValue = "D:/temp")
private String outputDir;
@Parameter(property = "projectDir", defaultValue = "${project.baseDir}")
private String projectDir;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("hello world.");
getLog().info(greeting);
// 相对路径
File outputDirFile = new File(this.outputDir);
getLog().info(outputDirFile.getAbsolutePath());
getLog().info("projectDir:" + projectDir);
try {
ClassLoader classLoader = getClassLoader();
String path = "D:/work_code/xxx_code/xxx-service/xxx/target/classes";
Path clientPath = Paths.get(path, "/cn/xxx/xxx/xxx/xxx/mapper");
scanDir(clientPath, classLoader);
} catch (Exception e) {
e.printStackTrace();
}
}
private void scanDir(Path clientPath, ClassLoader classLoader) throws Exception {
Files.list(clientPath).forEach(p -> {
try {
String filePath = p.toString();
// class文件路径
String clsPath = filePath.substring(filePath.indexOf("classes") + 8);
clsPath = clsPath.replace("\\", ".").replace(".class", "");
Class<?> aClass = classLoader.loadClass(clsPath);
Method[] methods = aClass.getMethods();
getLog().info("method size:" + methods.length);
} catch (Exception e) {
e.printStackTrace();
}
});
}
private ClassLoader getClassLoader() throws Exception {
String path = "D:/work_code/xxx_code/xxx-service/xxx/target/classes";
String appPath = "D:/work_code/xxx_code/xxx-service/xxx/target/classes";
URL url = new File(path).toURI().toURL();
URL appUrl = new File(appPath).toURI().toURL();
return new URLClassLoader(new URL[]{url, appUrl}, Thread.currentThread().getContextClassLoader());
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public String getOutputDir() {
return outputDir;
}
public void setOutputDir(String outputDir) {
this.outputDir = outputDir;
}
public String getProjectDir() {
return projectDir;
}
public void setProjectDir(String projectDir) {
this.projectDir = projectDir;
}
}
开发步骤
- 自己的类(入口)继承AbstractMojo
- 主类(入口)上添加注解@Mojo(name = "sayhi", threadSafe = true),name自定义
- 定义参数,@Parameter标识,参数设置属性和默认值等,参数定义好后可以在插件中配置后使用
- 打包
mvn clean install
- 其他项目中使用
mvn packageName:name-maven-plugin:version:mojoName<br/>
验证
3. 遇到的坑
主要是ClassLoader加载路径时加载不到class文件,原因是定义URL时,使用==file://==开头,后面改为URL url = new File(path).toURI().toURL()
即可
4. 2种启动方式及调试
- 命令方式
mvn packageName:pluginName:version:mojoName
- 插件点击方式
debug
参考
插件官网
mybatis-plus插件示例