博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Configure swagger with spring boot
阅读量:7125 次
发布时间:2019-06-28

本文共 8049 字,大约阅读时间需要 26 分钟。

If you haven’t starting working with spring boot yet, you will quickly find that it pulls out all the common configuration from across your applications. Recently I helped in an effort to modularize configuration and worked on creating a spring-boot-swagger starter project. This project, like other boot modules, would be included in the pom and you would enjoy the fruits of auto configuration.

If you aren't familiar with swagger, swagger is a "specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services". It has various integration points with java back end technologies (JAX-RS, scala, php, nodejs, etc) but even better it has separated the front end into a project called . So as long as your service complies to the spec you can have a pretty UI on top of your rest services. It does lack official support spring MVC though there are various projects on github that attempt to integrate the two, even I . Also there has been talk in .

We went with  simply due to the number of watchers/stars and it fit in pretty good with little effort. It can be integrated with traditional spring XML or through java config both ways requiring two properties to be set to specify the API version and the base path. With the direction of spring-boot, we wanted to abstract the dependency and defaults so consuming apps would just have to plug it in to the pom.xml. It lead us down a few options which we described below and in the end landed on #3 of Injecting ConfigurableApplicationContext in one of our auto configuration classes.

Option 1 - PropertyPlaceholderConfigurer

As martypitt / swagger-springmvc states in the documentation you can configure the properties programmatically with the PropertyPlaceholderConfigurer. We need the properties in , a class that manages profiles and properties, but PropertyPlaceholderConfigurer is not able to add properties to environment. PropertySourcesPlaceholderConfigurer uses Environment and not vice versa. Also, we wanted this in the spring boot module, not all consuming rest applications. In case this works for you, this is what the configuration would look like:

@Beanpublic static PropertyPlaceholderConfigurer swaggerProperties() throws UnknownHostException { // Swagger expects these to property values to be replaced. We don't want to propagate these to consumers of // this configuration, so we derive reasonable defaults here and configure the properties programmatically. Properties properties = new Properties(); properties.setProperty("documentation.services.basePath", servletContext.getContextPath()); // this property will be overridden at runtime, so the value here doesn't matter properties.setProperty("documentation.services.version", "REPLACE-ME"); PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer(); configurer.setProperties(properties); configurer.setIgnoreUnresolvablePlaceholders(true); return configurer; }

Option 2 - Implementing ApplicationContextInitializer

 is a call back interface for initializing ConfigurableApplicationContext prior to being refreshed typically used within web applications that require some programmatic initialization of the application context. So this would work great, on start up we can set the two properties but what it doesn't give us is the ability to get hold of a  through  because it fires to early on in the spring lifecycle.

So if your application will deploy to a single environment or if you want to require each of your applications to specify the properties required in the application.properties file, this solution might work for you. It would look something like this:

In your spring.factories within your boot starter project you would need to add:

org.springframework.context.ApplicationContextInitializer=com.levelup.SomeInitializer

Then add the following class

public class SwaggerApplicationContextInitializer implements        ApplicationContextInitializer
{ @Override public void initialize(ConfigurableApplicationContext applicationContext) { MutablePropertySources propertySources = applicationContext .getEnvironment().getPropertySources(); Map
propertyMap = new HashMap
(); propertyMap.put("documentation.services.basePath", "http://localhost:8080/participant"); propertyMap.put("documentation.services.version", "REPLACE-ME"); propertySources.addFirst(new MapPropertySource( "documentation.services", propertyMap)); } }

Option 3 - Injecting ConfigurableApplicationContext

At the end of the day this solution may not be spring certified and there probably another way to do it but worked. provides facilities to configure an application context in addition to the application context client methods. So we created a class that implements InitializingBean that allows us to react once all their properties have been set. It allows us to configure the properties need and then add them to the environment so when the DocumentationConfig looks for them, they are available.

@Configuration@AutoConfigureBefore(SwaggerAutoConfiguration.class) @EnableConfigurationProperties({ SwaggerBeanProperties.class }) public class SwaggerPropertiesAutoConfiguration implements InitializingBean, ServletContextAware { private ServletContext servletContext; @Autowired ConfigurableApplicationContext applicationContext; @Autowired SwaggerBeanProperties swaggerBeanProperties; @Override public void afterPropertiesSet() throws Exception { MutablePropertySources propertySources = applicationContext .getEnvironment().getPropertySources(); Map
propertyMap = new HashMap
(); propertyMap.put("documentation.services.basePath", getDocumentBasePath()); propertyMap.put("documentation.services.version", getDocumentVersion()); propertySources.addFirst(new MapPropertySource( "documentation.services", propertyMap)); } private String getDocumentBasePath() { if (swaggerBeanProperties.getBasePath() != null) { return swaggerBeanProperties.getBasePath(); } else { return servletContext.getContextPath(); } } private String getDocumentVersion() { if (swaggerBeanProperties.getVersion() != null) { return swaggerBeanProperties.getVersion(); } else { return "1.0"; } } @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } }

We all have heard it before, "we don't want the base configuration" so we created a @ConfigurationProperties class that will look for the properties and will be injected into SwaggerPropertiesAutoConfiguration above. If properties are set in the application we will apply them, otherwise we will look for the defaults in hopes to create consistency across all apps.

@AutoConfigureBefore(SwaggerPropertiesAutoConfiguration.class) @ConfigurationProperties(name = "documentation.services", ignoreUnknownFields = true) public class SwaggerBeanProperties { private String basePath; private String version; public String getBasePath() { return basePath; } public void setBasePath(String basePath) { this.basePath = basePath; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } }

The last class was simply to import the DocumentationConfig.class

@Configuration@Import(DocumentationConfig.class) public class SwaggerAutoConfiguration { }

Finally, the spring.factories

# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\boot.web.swagger.autoconfigure.SwaggerAutoConfiguration,\boot.web.swagger.autoconfigure.SwaggerPropertiesAutoConfigurationorg.springframework.context.ApplicationContextInitializer=

Spring-boot was made to solve the "we have ever which way to configure an application" syndrome but occasionally you still might have get dirty. It might not be perfect but it works for now. If you have suggestions or other ways this could be handled, let me know.

Configure swagger with spring boot posted by  on 16 April 2014

http://www.leveluplunch.com/blog/2014/04/16/spring-boot-swagger-springmvc-configuration/

 

转载地址:http://yiael.baihongyu.com/

你可能感兴趣的文章
ARM第二季度营收增长17%至3.5亿美元
查看>>
Incorporating Copying Mechanism in Sequence-to-Sequence Learning
查看>>
咸阳市位列智慧城市时空云建设年度考核全国第二名
查看>>
Spring 分析摘录
查看>>
IMF总裁:科技变革对于就业的意义何在
查看>>
突破性能瓶颈 东芝发布全新固态硬盘
查看>>
大数据助力农牧业转型升级
查看>>
90亿赔偿没戏了:法官拒甲骨文重审Android侵权案要求
查看>>
智能LED路灯有多种应用功能 将成为智慧城市发展的突破口
查看>>
论大数据对媒体融合的推进作用
查看>>
微软黑科技:DNA存储技术催生方糖大小的数据中心
查看>>
招聘新手段:录段语音来判断求职者是否适合岗位
查看>>
倪光南:大数据安全问题重要性远超数据安全
查看>>
应对网络威胁 有望不再被动“打补丁”
查看>>
老国企如何焕发新势能?致远互联“协同五环”锻造老而弥坚
查看>>
被戴尔收购的EMC宣布明年裁员:人数未定
查看>>
物联网时代MCU 将迎来三大发展趋势
查看>>
解决最后一米信号问题飞鱼星VF-E300全新上市
查看>>
智慧城市安全问题初探
查看>>
打造NFV环境下的专属性能
查看>>