一、背景介绍
最近恰巧遇到代码生成的相关任务,结合调研结果,现将自己的实验经历做个小结,
本文基于 SpringBoot + Mybatis 架构展开,代码生成以 Mybatis Generator 为核心,
同时,基于 FreeMarker 制作了自定义插件,拓展了 Mybatis Generator 的相关功能,
最终,实现了 DAO + Service + Controller 各层的自动代码生成。
二、 实验步骤
2.1 首先,实现自己的 Mybatis Generator 插件,用于生成 Service 和 Controller,
因为原生 generator 只能生成 DAO
打开 STS, 创建一个 maven 项目,maven-archetype-quickstart 类型即可
删除 src/test ,没啥用
编辑 pom.xml,添加 Mybatis 依赖、FreeMarker 依赖
<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>org.shida</groupId> <artifactId>mybatis3plugins</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>mybatis3plugins</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.6</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> </dependencies> </project>
修改 App.java 为 ServiceControllerPlugin.java,同时编辑内容为
package org.shida.mybatis3plugins; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; import org.mybatis.generator.api.GeneratedJavaFile; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import freemarker.core.ParseException; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import freemarker.template.MalformedTemplateNameException; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateNotFoundException; public class ServiceControllerPlugin extends PluginAdapter { public boolean validate(List<String> warnings) { return true; } @Override public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) { String javaRepositoryPackage = this.getContext().getJavaClientGeneratorConfiguration().getTargetPackage(); String javaMapperType = introspectedTable.getMyBatis3JavaMapperType(); String topPackage = javaRepositoryPackage.substring(0, javaRepositoryPackage.lastIndexOf('.')); String javaClassName = javaMapperType.substring(javaMapperType.lastIndexOf('.') + 1, javaMapperType.length()).replace("Mapper", ""); String targetProject = this.getContext().getJavaClientGeneratorConfiguration().getTargetProject(); Map<String, String> root = new HashMap<String, String>(); root.put("topPackage", topPackage); root.put("EntityName", javaClassName); root.put("entityName", new StringBuilder().append(Character.toLowerCase(javaClassName.charAt(0))) .append(javaClassName.substring(1)).toString()); genService(targetProject, topPackage, javaClassName, root); genController(targetProject, topPackage, javaClassName, root); return null; } @SuppressWarnings("deprecation") private void genService(String targetProject, String topPackage, String javaClassName, Map<String, String> root) { String dirPath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/service"; String filePath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/service/" + javaClassName + "Service.java"; File dir = new File(dirPath); File file = new File(filePath); if (file.exists()) { System.err.println(file + " already exists, it was skipped."); return; } else { try { dir.mkdirs(); file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } Configuration cfg = new Configuration(); cfg.setClassForTemplateLoading(this.getClass(), "/"); cfg.setObjectWrapper(new DefaultObjectWrapper()); try { Template temp = cfg.getTemplate("EntityService.ftl"); Writer out = new OutputStreamWriter(new FileOutputStream(file)); temp.process(root, out); out.flush(); } catch (TemplateNotFoundException e) { e.printStackTrace(); } catch (MalformedTemplateNameException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } @SuppressWarnings("deprecation") private void genController(String targetProject, String topPackage, String javaClassName, Map<String, String> root) { String dirPath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/controller"; String filePath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/controller/" + javaClassName + "Controller.java"; File dir = new File(dirPath); File file = new File(filePath); if (file.exists()) { System.err.println(file + " already exists, it was skipped."); return; } else { try { dir.mkdirs(); file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } Configuration cfg = new Configuration(); cfg.setClassForTemplateLoading(this.getClass(), "/"); cfg.setObjectWrapper(new DefaultObjectWrapper()); try { Template temp = cfg.getTemplate("EntityController.ftl"); Writer out = new OutputStreamWriter(new FileOutputStream(file)); temp.process(root, out); out.flush(); } catch (TemplateNotFoundException e) { e.printStackTrace(); } catch (MalformedTemplateNameException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } }
该 Plugin 继承了 PluginAdapter ,通过重写 contextGenerateAdditionalJavaFiles 方法实现额外文件的生成
代码中,调用了 freemarker 模板,需要把模板放至 src/main/resources 文件夹下
注意,这里为了简单,我只示例了 实例创建方法 create/insert
Service 模板:EntityService.ftl ,
package ${topPackage}.service; import ${topPackage}.domain.${EntityName}; import ${topPackage}.repository.${EntityName}Mapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * generated by shida's plugin */ @Service public class ${EntityName}Service { @Autowired private ${EntityName}Mapper ${entityName}Mapper; public int insert(${EntityName} ${entityName}) { return ${entityName}Mapper.insert(${entityName}); } }
Controller 模板:EntityController.ftl
package ${topPackage}.controller; import ${topPackage}.domain.${EntityName}; import ${topPackage}.service.${EntityName}Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * generated by shida's plugin */ @RestController @RequestMapping("/api") public class ${EntityName}Controller { @Autowired private ${EntityName}Service ${entityName}Service; @PostMapping("/${entityName}/create") public int create(@RequestBody ${EntityName} ${entityName}) { return ${entityName}Service.insert(${entityName}); } }
编译插件并安装到本地仓库,mvn install
2.2 然后,我们创建一个 SpringBoot 项目,同时整合 MyBatis 和 Mybatis Generator
打开 STS, 创建一个 maven 项目,maven-archetype-quickstart 类型即可
删除 src/test ,这里没什么用
修改 pom.xml,添加相关依赖和插件,主要是 SpringBoot 和 Mybatis 以及 Archetype 相关的
注意,这里同时引用了 我们在 2.1 步生成的插件 mybatis3plugins
修改后的最后版本为:
<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>org.shida</groupId> <artifactId>gendemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>gendemo</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <verbose>false</verbose> <overwrite>true</overwrite> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.shida</groupId> <artifactId>mybatis3plugins</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-archetype-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </build> </project>
编写 SpringBoot 启动入口类前,首先修改包名,将 org.shida.gendemo 修改为 org.shida
之所以这么改,是为了防止自动生成代码时产生错误的包问题
然后,修改 App.java 的内容,设置为 SpringBoot 启动类,最终 App.java 的内容为
package org.shida; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; @Configuration @SpringBootApplication @MapperScan(basePackages = "org.shida") public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
在 src/main 下建立 resources 文件夹,然后在 resources 文件夹下创建 application.yml 文件
该文件是 SpringBoot 的配置文件,最终配置为(数据库信息改成你自己真实使用的)
spring: jackson: serialization.indent_output: true datasource: driver-class-name: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource url: jdbc:mysql://127.0.0.1:3306/generate?useUnicode=true&characterEncoding=utf8&useSSL=false username: shida password: shida server: port: 9000
接着,在 resources 文件夹下创建 generatorConfig.xml,设置代码生成的相关信息
注意,这里插件加入了我们自己的插件,org.shida.mybatis3plugins.ServiceControllerPlugin
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="mysql.properties" /> <context id="mysqlTables" targetRuntime="MyBatis3"> <property name="javaFileEncoding" value="UTF-8" /> <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter" /> <plugin type="org.mybatis.generator.plugins.SerializablePlugin" /> <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" /> <plugin type="org.mybatis.generator.plugins.ToStringPlugin" /> <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/> <plugin type="org.mybatis.generator.plugins.MapperAnnotationPlugin" /> <plugin type="org.shida.mybatis3plugins.ServiceControllerPlugin" /> <commentGenerator> <property name="suppressDate" value="true" /> <property name="suppressAllComments" value="true" /> </commentGenerator> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}" /> <!--指定生成的类型为java类型,避免数据库中number等类型字段 --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--自动生成的实体的存放包路径 --> <javaModelGenerator targetPackage="org.shida.domain" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <sqlMapGenerator targetPackage="org.shida.xml" targetProject="src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="org.shida.repository" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="rootInterface" value="" /> </javaClientGenerator> </context> </generatorConfiguration>
可以看到 generatorConfig.xml 内引用了 mysql.properties,
因此,我们在 resources 内放置 mysql.properties ,数据库信息写成你的真实信息
jdbc.url=jdbc:mysql://127.0.0.1:3306/generate?useUnicode=true&characterEncoding=utf-8&useSSL=false jdbc.username=shida jdbc.password=shida
至此,SpringBoot 模板工程就已经建好了,我们基于此生成 Archetype
执行,mvn archetype:create-from-project
2.3 编辑模板,设置变量替换项
build 成功后,我们把 target/generated-sources/archetype 拷贝到一个工作目录,
然后我们使用 vscode 打开 archetype 文件夹
删除不必要的文件,下边3个,这是 eclipse 相关的,对于模板项目没用
src\main\resources\archetype-resources\.settings、
src\main\resources\archetype-resources\.classpath、
src\main\resources\archetype-resources\.project
修改 src\main\resources\META-INF\maven\archetype-metadata.xml
这里配置了 archetype 需要传入的参数(主要是db信息),以及打包的文件信息,最后修改内容为
<?xml version="1.0" encoding="UTF-8"?> <archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="gendemo" xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <requiredProperties> <requiredProperty key="dbHost" > <defaultValue>127.0.0.1</defaultValue> </requiredProperty> <requiredProperty key="dbPort" > <defaultValue>3306</defaultValue> </requiredProperty> <requiredProperty key="dbName" /> <requiredProperty key="dbTables" /> <requiredProperty key="dbUser" /> <requiredProperty key="dbPassword" /> </requiredProperties> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> </fileSets> </archetype-descriptor>
需要注意的是,除了在 archetype-metadata.xml 中配置参数外,还需要在
src\test\resources\projects\basic\archetype.properties 中指定,参数名与archetype-metadata是对应的
属性任意写,基于模板创建项目时是要以实际传入为准的
#Sat May 26 14:10:10 CST 2018 package=it.pkg version=0.1-SNAPSHOT groupId=archetype.it artifactId=basic dbHost=127.0.0.1 dbPort=3306 dbName=database dbTables=table dbUser=root dbPassword=root
然后,我们修改源码文件,将变量用占位符替换
application.xml
spring: jackson: serialization.indent_output: true datasource: driver-class-name: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource url: jdbc:mysql://${dbHost}:${dbPort}/${dbName}?useUnicode=true&characterEncoding=utf8&useSSL=false username: ${dbUser} password: ${dbPassword} server: port: 9000
mysql.properties
#set( $symbol_pound = '#' ) #set( $symbol_dollar = '$' ) #set( $symbol_escape = '\' ) jdbc.url=jdbc:mysql://${dbHost}:${dbPort}/${dbName}?useUnicode=true&characterEncoding=utf-8&useSSL=false jdbc.username=${dbUser} jdbc.password=${dbPassword}
generatorConfig.xml
#set( $symbol_pound = '#' ) #set( $symbol_dollar = '$' ) #set( $symbol_escape = '\' ) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="mysql.properties" /> <context id="mysqlTables" targetRuntime="MyBatis3"> <property name="javaFileEncoding" value="UTF-8" /> <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter" /> <plugin type="org.mybatis.generator.plugins.SerializablePlugin" /> <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" /> <plugin type="org.mybatis.generator.plugins.ToStringPlugin" /> <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/> <plugin type="org.mybatis.generator.plugins.MapperAnnotationPlugin" /> <plugin type="org.shida.mybatis3plugins.ServiceControllerPlugin" /> <commentGenerator> <property name="suppressDate" value="true" /> <property name="suppressAllComments" value="true" /> </commentGenerator> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="${symbol_dollar}{jdbc.url}" userId="${symbol_dollar}{jdbc.username}" password="${symbol_dollar}{jdbc.password}" /> <!--指定生成的类型为java类型,避免数据库中number等类型字段 --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--自动生成的实体的存放包路径 --> <javaModelGenerator targetPackage="${package}.domain" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <sqlMapGenerator targetPackage="${package}.xml" targetProject="src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="${package}.repository" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="rootInterface" value="" /> </javaClientGenerator> #foreach( $tableName in $dbTables.split(",") ) #set($upperTableName = $tableName.substring(0, 1).toUpperCase() + $tableName.substring(1)) <table schema="${dbName}" tableName="${tableName}" domainObjectName="$upperTableName"> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="mysql" identity="true" /> </table> #end </context> </generatorConfiguration>
修改 pom.xml,删除 maven-archetype-plugin ,已经不需要了,删除
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-archetype-plugin</artifactId> <version>2.2</version> </plugin>
然后,我们执行 mvn install 安装该 archetype 到仓库
2.4 验证 archetype
首先设置 sts maven setting.xml 路径为正确路径
新建一个 maven 项目,勾选 Include snapshot archetypes,选择我们自己的 archetype
需要填写 DB 相关参数,填写真实的 db 信息,多个 table 用 逗号 分隔
生成项目结构为:
然后,首先生成代码,执行 mvn mybatis-generator:generate
红框内的代码自动生成了,运行 App.java
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.2.RELEASE) 2018-05-27 14:53:11.757 INFO 5768 --- [ main] org.shida.test.App : Starting App on auto-PC with PID 5768 (C:\Users\auto\Documents\workspace-sts-3.9.4.RELEASE\test\target\classes started by auto in C:\Users\auto\Documents\workspace-sts-3.9.4.RELEASE\test) 2018-05-27 14:53:11.762 INFO 5768 --- [ main] org.shida.test.App : No active profile set, falling back to default profiles: default 2018-05-27 14:53:11.858 INFO 5768 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@19bb07ed: startup date [Sun May 27 14:53:11 CST 2018]; root of context hierarchy 2018-05-27 14:53:12.658 INFO 5768 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Generic.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] 2018-05-27 14:53:13.656 INFO 5768 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9000 (http) 2018-05-27 14:53:13.697 INFO 5768 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2018-05-27 14:53:13.698 INFO 5768 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.31 2018-05-27 14:53:13.708 INFO 5768 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\java\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;D:/jre/bin/server;D:/jre/bin;D:/jre/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\java\bin;D:\apache-maven-3.5.3\bin;;C:\Program Files (x86)\Microsoft VS Code\bin;D:\spring-tool-suite-3.9.4.RELEASE-e4.7.3a-win32-x86_64\sts-bundle\sts-3.9.4.RELEASE;;.] 2018-05-27 14:53:13.819 INFO 5768 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2018-05-27 14:53:13.820 INFO 5768 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1965 ms 2018-05-27 14:53:14.008 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2018-05-27 14:53:14.016 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2018-05-27 14:53:14.462 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-27 14:53:14.825 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@19bb07ed: startup date [Sun May 27 14:53:11 CST 2018]; root of context hierarchy 2018-05-27 14:53:14.917 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/price/create],methods=[POST]}" onto public int org.shida.test.controller.PriceController.create(org.shida.test.domain.Price) 2018-05-27 14:53:14.918 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/user/create],methods=[POST]}" onto public int org.shida.test.controller.UserController.create(org.shida.test.domain.User) 2018-05-27 14:53:14.920 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2018-05-27 14:53:14.921 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2018-05-27 14:53:14.956 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-27 14:53:14.956 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-27 14:53:15.267 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-05-27 14:53:15.268 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure 2018-05-27 14:53:15.274 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource] 2018-05-27 14:53:15.321 INFO 5768 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9000 (http) with context path '' 2018-05-27 14:53:15.324 INFO 5768 --- [ main] org.shida.test.App : Started App in 4.029 seconds (JVM running for 4.725)
应用成功启动,然后实验一下,使用 postman,发送一条请求
可以看到,已经成功录入数据
三、 总结
整体功能,本文从流程上已经走通了:
首先编写自定义的generator plugin,实现对 Service 和 Controller 的代码生成,
然后定制一个SpringBoot 模板工程,打包成 archetype
以后直接基于该 archetype 就可以快速创建项目了,项目已经集成好了自动代码生成框架,
可以很方便地生成基础代码,至于 Service 和 Controller 功能代码的完善,就交给阅读本文的您去逐渐完善吧!