自定义SpringBoot+Swagger中@ApiModel默认名称
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义SpringBoot+Swagger中@ApiModel默认名称相关的知识,希望对你有一定的参考价值。
参考技术A 在 Spring 中集成 swagger 文档功能,需要通过 @ApiModel 注解修饰出入参的类,但是如果有两个不同包下的相同名称的类都使用了 @ApiModel 注解时,会导致文档被覆盖,例如:上面两个类生成出来的文档会变成一个 swagger model :
从而导致接口文档显示错误:
通过修改@ApiModel 的 value 属性,来规避同名冲突,修改之后为:
可以看到生成了两个 swagger model :
把两个类名做修改,让类名不冲突即可。
然而上面解决冲突的方式还是太麻烦了,定义一个文档的出入参类而已,还要考虑类重名的问题,这种增加心智负担和工作量的问题应该要尽量避免掉的,我在想有没有可能做到每个类上只需要加上 @ApiModel 注解就行,剩下的冲突问题全部不用考虑。
于是乎通过跟踪源码,找到了 swagger model 名称生成的地方,详见:github
可以看到取名的逻辑是,优先取 @ApiModel 的 value 值,如果没有就会使用 defaultTypeName ,跟进去一看, defaultTypeName 是直接取类的 简称 ,代码如下:
正是因为默认情况下取类的 简称 ,导致不同包名下的同名类生成出来的 swagger model 被覆盖。原因已经分析出来了,接下来其实就是看看能不能定制化这个 super.nameFor(type) 方法了,然而很遗憾这个方法是写死的,没地方下手,但是 ApiModelTypeNameProvider 这个类上两个注解 @Component 和 @Order 已经明示了这个是一个 Spring bean ,并且是通过 Spring插件机制进行加载的 ,所以可以自定义一个插件来完成,在默认时通过完整的类路径和类名来生成唯一的 swagger model ,代码如下:
效果如下:
通过这一个小小的优化,就可以减少许多团队中不必要的沟通成本,让我们能更专注于业务开发。
SpringBoot中级教程之SpringBoot自定义配置
SpringBoot中级教程之SpringBoot自定义配置(十一)
前言首先力推下我的开源项目
http://git.oschina.net/wangkang_daydayup/swagger-doc 这是一个完全利用spring boot开发的项目,拯救了springfox-swagger污染代码的问题,完全利用java-doc来实现,学习成本几乎是0
1.介绍
在Spring的代码中随处可见的@EnableAutoConfiguration
、@EnableWebMvc
、@EnableTransactionManagement
这些注解,通过使用这些注解来开启某项功能,下面的
例子就是来讲解如何定义自己的@EnableXXX
使用场景
官方介绍:If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.
Auto-configuration can be associated to a “starter” that provides the auto-configuration code as well as the typical libraries that you would use with it. We will first cover what you need to know to build your own auto-configuration and we will move on to the typical steps required to create a custom starter.
大概意思是这样的:如果你在一个开发共享库的公司,或者是你想开发自己的auto-configuration,也就是说为spring boot开发一些自动配置的模块的时候,这个时候就需要用到这个技术,
完全可以通过一个注解或者引入一个jar包就开启这个功能
2.快速开始
下面是pom的配置 主要核心配置是spring-boot-configuration-processor
,这个是用来对注解进行处理的,官方解释是
You can easily generate your own configuration meta-data file from items annotated with @ConfigurationProperties
2.1 首先是pom.xml的配置
<?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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-11</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.4.RELEASE</version>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2 声明一个注解@EnableDemo
@EnableDemo
是自己定义的一个注解,用来启用DemoConfig
这个类当中的内容,其实原理跟扫描或者是配置xml是差不多的
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = java.lang.annotation.ElementType.TYPE )
@Documented
@Import( DemoConfig.class )
@Configuration
public @interface EnableDemo
String param() default "";
DemoConfig
中仅仅只打印了一个初始化日志当作测试而已 ,同时DemoProperties
也被当做配置注入进来,并且打印出来具体的配置数据
@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoConfig
@Autowired
private DemoProperties demoProperties;
Logger logger = LoggerFactory.getLogger(getClass());
@PostConstruct
public void init()
logger.info("######DemoConfig init####### demoProperties is ", demoProperties.toString());
如何拿到@EnableDemo注解中参数的配置呢
这里针对DemoConfig做了一个优化,代码如下所示
@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoConfig implements ImportAware, BeanClassLoaderAware
@Autowired
private DemoProperties demoProperties;
Logger logger = LoggerFactory.getLogger(getClass());
private ClassLoader classLoader;
private String param;
@PostConstruct
public void init()
logger.info("######DemoConfig init####### param is demoProperties is ", param, demoProperties.toString());
@Override
public void setImportMetadata(AnnotationMetadata annotationMetadata)
Map<String, Object> enableAttrMap = annotationMetadata.getAnnotationAttributes(EnableDemo.class.getName());
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
if (enableAttrs == null)
// search parent classes
Class<?> currentClass = ClassUtils.resolveClassName(annotationMetadata.getClassName(), classLoader);
for (Class<?> classToInspect = currentClass; classToInspect != null; classToInspect = classToInspect
.getSuperclass())
EnableDemo enableDemo = AnnotationUtils.findAnnotation(classToInspect, EnableDemo.class);
if (enableDemo == null)
continue;
enableAttrMap = AnnotationUtils.getAnnotationAttributes(enableDemo);
enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
this.param = enableAttrs.getString("param");
@Override
public void setBeanClassLoader(ClassLoader classLoader)
this.classLoader = classLoader;
上面流程大概是实现了ImportAware接口,也就是注解被解析完之后的一个回调,然后通过这个回调拿到具体的参数而已
大概流程基本都完成了,这样就能够完成一个简单的@EnableDemo
配置
2.3 yaml自动提示
在spring boot中如果使用application.yaml
进行项目配置,会产生一个自动提示,这个自动提示可以自己定义开发的
之前上面代码中有个DemoProperties
,现在可以继续看看,首先是@ConfigurationProperties
这个注解,通过prefix来配置前缀,假设我们配置的前缀是springboot.demo
@ConfigurationProperties(prefix = "springboot.demo")
public class DemoProperties
private String name;
private String select;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getSelect()
return select;
public void setSelect(String select)
this.select = select;
@Override
public String toString()
return "DemoProperties" + "name='" + name + '\\'' + ", select='" + select + '\\'' + '';
如果想让上述的配置在application.yaml
进行自动提示,需要进行两步,第一步是确保maven中有processor
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
第二步需要对idea
编辑器进行配置Preferences->Build, Execution, Deployment->Compile->Annotation Processors->Enable annonation processing
钩上这个选项,这样的话就会自动在target/classes/META-INF中生成spring-configuration-metadata.json
文件
下面是效果图
总体代码在
http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/tree/master/springboot-11
扩展
spring.factories
简单的说一下spring.factories
这个主要是提供了一个功能,就是自动配置,不需要使用@EnableXXX来开启,也就是说只要你用了springboot,并且依赖了一个jar包,这个jar包就会自动进行初始化
那么这个过程就是使用了spring.factories
这个文件配置
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.start.config.AudoDemoConfig
下面的com.start.config.AudoDemoConfig
就是自己定义的config,springboot启动的时候就会自动扫描,具体使用可以查看下面这个项目中的com.start.config.AudoDemoConfig
http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/tree/master/springboot-11
spring-configuration-metadata.json
如果仔细看target/classes/META-INF中,你就会发现有那么一个文件的存在spring-configuration-metadata.json
,这个就是整个application.yaml
提示的配置,他是自动生成的
"hints": [],
"groups": [
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo",
"type": "com.start.config.DemoProperties"
],
"properties": [
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo.name",
"type": "java.lang.String"
,
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo.select",
"type": "java.lang.String"
]
具体的英文文档可以查看http://docs.spring.io/spring-boot/docs/current/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor
这个json文件主要分为三个部分,首先是group,group代表一个类,比如DemoProperties,一个项目中存在多个group,而propertis代表是类里面的属性通过sourceType
来确定是那一个类的
然后是hints,语意上来说就是提示
hints的使用
具体项目中的使用,可以通过在resources/META-INF 中放入spring-configuration-metadata.json
文件,文件内容如下
"hints": [
"name": "springboot.demo.select",
"values": [
"value": "1",
"description": "1的描述"
,
"value": "2",
"description": "2的描述"
]
],
"groups": [
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo",
"type": "com.start.config.DemoProperties"
],
"properties": [
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo.name",
"type": "java.lang.String"
,
"sourceType": "com.start.config.DemoProperties",
"name": "springboot.demo.select",
"type": "java.lang.String"
]
效果图
以上是关于自定义SpringBoot+Swagger中@ApiModel默认名称的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot中级教程之SpringBoot自定义配置
SpringBoot中级教程之SpringBoot自定义配置
SpringBoot中级教程之SpringBoot自定义配置