-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
351768593
committed
Aug 24, 2021
0 parents
commit a6113b6
Showing
12 changed files
with
634 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Project exclude paths | ||
/target/ | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?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> | ||
|
||
<groupId>firok.spring</groupId> | ||
<artifactId>mvci</artifactId> | ||
<version>1.0.0</version> | ||
<description>An annotation processing tool to generate MVC code from JavaBean(s).</description> | ||
|
||
<properties> | ||
<java.version>16</java.version> | ||
<maven.compiler.source>16</maven.compiler.source> | ||
<maven.compiler.target>16</maven.compiler.target> | ||
</properties> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.7.0</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<source>16</source> | ||
<target>16</target> | ||
</configuration> | ||
</plugin> | ||
|
||
</plugins> | ||
</build> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# MVC Introspector | ||
|
||
基于 Annotation Processing Tool 技术, 工作于编译期, | ||
为 SpringBoot 生成一整套 MVC CRUD 结构. | ||
|
||
## 使用方式 | ||
|
||
* 在项目中引入 MVC Introspector 依赖 | ||
* 在 `META-INF/services/` 目录下建立文件 `javax.annotation.processing.Processor` | ||
内容为 | ||
```text | ||
firok.spring.mvci.MVCIntrospectProcessor | ||
``` | ||
* 启用开发环境中的 ADT 功能 | ||
* 为数据库表创建对应的 JavaBean 实体类, 并标注 `@BeanIntrospective` 注解 | ||
* 重新编译并启动项目 | ||
|
||
### 自定义生成模板 | ||
|
||
修改 `@MVCIntrospective` 注解中的 `xxxTemplate` 值即可调整相关结构的生成模板 | ||
|
||
> 将值设为 `firok.spring.mvci.Constants.DISABLE` (`"##DISABLE##"`) 会禁用相关结构生成 | ||
> 如果不想重复写多次冗长的生成模板, 可以将模板字符串定义为静态常量, 再在注解中使用 | ||
默认的模板定义在 `firok.spring.mvci.internal.DefaultXXXTemplate` 下. | ||
|
||
创建自定义模板时, 如下键会在结构生成时被替换: | ||
|
||
键|含义|示例替换值 | ||
-|-|- | ||
`##BEAN_NAME_FULL##` | 实体完整名 | `TestBean`, `TestEntity`, `BeanTest`, `EntityTest` | ||
`##BEAN_NAME_SHORT##` | 实体简称 | `Test` | ||
`##MAPPER_NAME##` | Mapper 名称 | `TestMapper` | ||
`##SERVICE_NAME##` | Service 名称 | `TestService` | ||
`##SERVICE_IMPL_NAME##` | Service Impl 名称 | `TestServiceImpl` | ||
`##CONTROLLER_NAME##` | Controller 名称 | `TestController` | ||
`##BEAN_PACKAGE##` | 实体位置 | `firok.spring.demo.bean`, `firok.spring.demo.entity` | ||
`##MAPPER_PACKAGE##` | Mapper 位置 | `firok.spring.demo.mapper` | ||
`##SERVICE_PACKAGE##` | Service 位置 | `firok.spring.demo.service` | ||
`##SERVICE_IMPL_PACKAGE##` | Service Impl 位置 | `firok.spring.demo.service.impl` | ||
`##CONTROLLER_PACKAGE##` | Controller 位置 | `firok.spring.demo.controller` | ||
|
||
### 自定义生成位置和名称 | ||
|
||
修改 `@MVCIntrospective` 注解中的 `xxxPackage` 值即可调整相关结构的生成位置; 修改 `xxxName` 即可调整相关结构名称. | ||
|
||
## 注意 | ||
|
||
**MVCI 本身** 不基于 SpringBoot 和 MybatisPlus, 但是 **MVCI 默认的结构代码模板** 基于 SpringBoot 和 MybatisPlus. | ||
所以默认情况下需为编译环境引入相关依赖, 否则项目无法通过编译. | ||
|
||
一个可用的依赖配置为: | ||
|
||
```xml | ||
<dependency> | ||
<groupId>com.baomidou</groupId> | ||
<artifactId>mybatis-plus-boot-starter</artifactId> | ||
<version>3.4.3.2</version> | ||
</dependency> | ||
``` | ||
|
||
此外, 您需要正确提供数据库驱动等依赖, 否则项目可能无法正常运行. | ||
|
||
MVCI 仅于 **Java16 环境** 下经过测试. 更低 Java 版本中仍可能使用, 但是您需要手动调整 `firok.spring.mvci.MVCIntrospectProcessor` 上的 `@SupportedSourceVersion` 注解值. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package firok.spring.mvci; | ||
|
||
import firok.spring.mvci.internal.DefaultControllerTemplate; | ||
import firok.spring.mvci.internal.DefaultMapperTemplate; | ||
import firok.spring.mvci.internal.DefaultServiceImplTemplate; | ||
import firok.spring.mvci.internal.DefaultServiceTemplate; | ||
|
||
public final class Constants | ||
{ | ||
public static final String DEFAULT_MAPPER_TEMPLATE = DefaultMapperTemplate.VALUE; | ||
|
||
public static final String DEFAULT_SERVICE_TEMPLATE = DefaultServiceTemplate.VALUE; | ||
|
||
public static final String DEFAULT_SERVICE_IMPL_TEMPLATE = DefaultServiceImplTemplate.VALUE; | ||
|
||
public static final String DEFAULT_CONTROLLER_TEMPLATE = DefaultControllerTemplate.VALUE; | ||
|
||
/** | ||
* 如果标注为 DISABLE, 将不会生成指定结构 | ||
*/ | ||
public static final String DISABLE = "##DISABLE##"; | ||
|
||
public static final String DEFAULT = "##DEFAULT##"; | ||
} |
118 changes: 118 additions & 0 deletions
118
src/main/java/firok/spring/mvci/MVCIntrospectProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package firok.spring.mvci; | ||
|
||
import firok.spring.mvci.internal.IntrospectContext; | ||
|
||
import javax.annotation.processing.*; | ||
import javax.lang.model.SourceVersion; | ||
import javax.lang.model.element.Element; | ||
import javax.lang.model.element.TypeElement; | ||
import javax.lang.model.util.Elements; | ||
import javax.lang.model.util.Types; | ||
import javax.tools.Diagnostic; | ||
import javax.tools.JavaFileObject; | ||
import java.io.Writer; | ||
import java.util.Set; | ||
|
||
import static firok.spring.mvci.Constants.DISABLE; | ||
|
||
@SupportedAnnotationTypes("firok.spring.mvci.MVCIntrospective") | ||
@SupportedSourceVersion(SourceVersion.RELEASE_16) | ||
public class MVCIntrospectProcessor extends AbstractProcessor | ||
{ | ||
private Types typeUtils; | ||
private Elements elementUtils; | ||
private Filer filer; | ||
private Messager messager; | ||
private void printNote(Object obj) | ||
{ | ||
messager.printMessage(Diagnostic.Kind.NOTE,"[MVCI] " + obj); | ||
} | ||
private void printWarning(Object obj) | ||
{ | ||
messager.printMessage(Diagnostic.Kind.WARNING,"[MVCI] " + obj); | ||
} | ||
private void printError(Object obj) | ||
{ | ||
messager.printMessage(Diagnostic.Kind.ERROR,"[MVCI] " + obj); | ||
} | ||
|
||
public MVCIntrospectProcessor() | ||
{ } | ||
|
||
@Override | ||
public synchronized void init(ProcessingEnvironment processingEnv) { | ||
super.init(processingEnv); | ||
typeUtils = processingEnv.getTypeUtils(); | ||
elementUtils = processingEnv.getElementUtils(); | ||
filer = processingEnv.getFiler(); | ||
messager = processingEnv.getMessager(); | ||
|
||
messager.printMessage(Diagnostic.Kind.NOTE,"MVC Introspector ADT 初始化完成"); | ||
} | ||
|
||
private void genJavaSource(String location,String content) throws Exception | ||
{ | ||
JavaFileObject jfo = filer.createSourceFile(location); | ||
try(Writer jw = jfo.openWriter()) | ||
{ | ||
jw.write(content); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) | ||
{ | ||
Set<? extends Element> setElements = roundEnv.getElementsAnnotatedWith(MVCIntrospective.class); | ||
printNote("读取并处理 MVC 结构"); | ||
for(Element ele : setElements) | ||
{ | ||
if(ele instanceof TypeElement te) | ||
{ | ||
var anno = ele.getAnnotation(MVCIntrospective.class); | ||
var context = new IntrospectContext(te,anno); | ||
|
||
try | ||
{ | ||
String content; // content to generate | ||
String qn; // qualified name | ||
GEN_MAPPER: | ||
{ | ||
if(DISABLE.equals(anno.mapperTemplate())) break GEN_MAPPER; | ||
content = context.pipeline(anno.mapperTemplate()); | ||
qn = context.mapperPackage + "." + context.mapperName; | ||
genJavaSource(qn,content); | ||
} | ||
GEN_SERVICE: | ||
{ | ||
if(DISABLE.equals(anno.serviceTemplate())) break GEN_SERVICE; | ||
content = context.pipeline(anno.serviceTemplate()); | ||
qn = context.servicePackage + "." + context.serviceName; | ||
genJavaSource(qn,content); | ||
} | ||
GEN_SERVICE_IMPL: | ||
{ | ||
if(DISABLE.equals(anno.serviceImplTemplate())) break GEN_SERVICE_IMPL; | ||
content = context.pipeline(anno.serviceImplTemplate()); | ||
qn = context.serviceImplPackage + "." + context.serviceImplName; | ||
genJavaSource(qn,content); | ||
} | ||
GEN_CONTROLLER: | ||
{ | ||
if(DISABLE.equals(anno.controllerTemplate())) break GEN_CONTROLLER; | ||
content = context.pipeline(anno.controllerTemplate()); | ||
qn = context.controllerPackage + "." + context.controllerName; | ||
genJavaSource(qn,content); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
printError("为 [%s] 生成结构失败: %s".formatted(context.beanNameFull,e.getLocalizedMessage())); | ||
} | ||
|
||
printNote("为 [%s] 生成结构成功".formatted(context.beanNameFull)); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package firok.spring.mvci; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import static firok.spring.mvci.Constants.*; | ||
|
||
/** | ||
* 标记在 JavaBean 上 | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.TYPE) | ||
public @interface MVCIntrospective | ||
{ | ||
/* == 实体信息 == */ | ||
|
||
String beanPackage() default DEFAULT; | ||
|
||
String beanNameFull() default DEFAULT; | ||
|
||
String beanNameShort() default DEFAULT; | ||
|
||
/* == 结构名称 == */ | ||
|
||
String mapperName() default DEFAULT; | ||
|
||
String serviceName() default DEFAULT; | ||
|
||
String serviceImplName() default DEFAULT; | ||
|
||
String controllerName() default DEFAULT; | ||
|
||
/* == 结构模板 == */ | ||
|
||
String mapperTemplate() default DEFAULT_MAPPER_TEMPLATE; | ||
|
||
String serviceTemplate() default DEFAULT_SERVICE_TEMPLATE; | ||
|
||
String serviceImplTemplate() default DEFAULT_SERVICE_IMPL_TEMPLATE; | ||
|
||
String controllerTemplate() default DEFAULT_CONTROLLER_TEMPLATE; | ||
|
||
/* == 结构位置 == */ | ||
|
||
String mapperPackage() default DEFAULT; | ||
|
||
String servicePackage() default DEFAULT; | ||
|
||
String serviceImplPackage() default DEFAULT; | ||
|
||
String controllerPackage() default DEFAULT; | ||
} |
Oops, something went wrong.