|
1 | 1 | package com.spring4all.swagger; |
2 | 2 |
|
3 | | -import com.google.common.base.Predicates; |
4 | | -import lombok.RequiredArgsConstructor; |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.List; |
| 5 | +import java.util.Map; |
| 6 | +import java.util.function.Predicate; |
| 7 | +import java.util.stream.Collectors; |
| 8 | + |
| 9 | +import org.springframework.beans.BeansException; |
| 10 | +import org.springframework.beans.factory.BeanFactory; |
| 11 | +import org.springframework.beans.factory.BeanFactoryAware; |
| 12 | +import org.springframework.beans.factory.annotation.Autowired; |
| 13 | +import org.springframework.beans.factory.config.BeanDefinition; |
| 14 | +import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| 15 | +import org.springframework.beans.factory.support.GenericBeanDefinition; |
| 16 | +import org.springframework.boot.context.properties.EnableConfigurationProperties; |
5 | 17 | import org.springframework.context.annotation.Bean; |
6 | 18 | import org.springframework.context.annotation.Configuration; |
| 19 | + |
| 20 | +import com.google.common.base.Predicates; |
| 21 | + |
7 | 22 | import springfox.documentation.builders.ApiInfoBuilder; |
8 | 23 | import springfox.documentation.builders.RequestHandlerSelectors; |
9 | 24 | import springfox.documentation.builders.RequestParameterBuilder; |
|
14 | 29 | import springfox.documentation.spi.DocumentationType; |
15 | 30 | import springfox.documentation.spring.web.plugins.Docket; |
16 | 31 |
|
17 | | -import java.util.ArrayList; |
18 | | -import java.util.Collections; |
19 | | -import java.util.List; |
20 | | -import java.util.function.Predicate; |
21 | | -import java.util.stream.Collectors; |
22 | | - |
23 | | -import static java.util.Collections.singletonList; |
24 | | - |
25 | 32 | /** |
26 | 33 | * @author 翟永超 |
27 | | - * Create date:2017/8/7. |
28 | | - * My blog: http://blog.didispace.com |
| 34 | + * @Create date:2017/8/7. |
| 35 | + * @Update date:2021/8/13 |
| 36 | + * @My blog: http://blog.didispace.com |
29 | 37 | */ |
30 | 38 | @Configuration |
31 | | -public class DocketConfiguration { |
| 39 | +@EnableConfigurationProperties(SwaggerProperties.class) |
| 40 | +public class DocketConfiguration implements BeanFactoryAware { |
32 | 41 |
|
| 42 | + private BeanFactory beanFactory; |
| 43 | + |
| 44 | + @Autowired |
33 | 45 | private SwaggerProperties swaggerProperties; |
34 | | - private SwaggerAuthorizationConfiguration swaggerAuthorizationConfiguration; |
35 | 46 |
|
36 | | - public DocketConfiguration(SwaggerProperties swaggerProperties, |
37 | | - SwaggerAuthorizationConfiguration swaggerAuthorizationConfiguration) { |
38 | | - this.swaggerProperties = swaggerProperties; |
39 | | - this.swaggerAuthorizationConfiguration = swaggerAuthorizationConfiguration; |
| 47 | + private static final String BEAN_NAME = "spring-boot-starter-swagger-"; |
| 48 | + |
| 49 | + @Override |
| 50 | + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
| 51 | + this.beanFactory = beanFactory; |
40 | 52 | } |
41 | 53 |
|
| 54 | + /** |
| 55 | + * Create the corresponding configuration for DocumentationPluginRegistry |
| 56 | + */ |
42 | 57 | @Bean |
43 | | - public Docket createRestApi() { |
44 | | - // 文档的基础信息配置 |
45 | | - Docket builder = new Docket(DocumentationType.SWAGGER_2) |
46 | | - .host(swaggerProperties.getHost()) |
47 | | - .apiInfo(apiInfo(swaggerProperties)); |
48 | | - |
49 | | - // 安全相关的配置 |
50 | | - builder.securityContexts(Collections.singletonList(swaggerAuthorizationConfiguration.securityContext())); |
51 | | - if ("BasicAuth".equalsIgnoreCase(swaggerAuthorizationConfiguration.getType())) { |
52 | | - builder.securitySchemes(Collections.singletonList(swaggerAuthorizationConfiguration.basicAuth())); |
53 | | - } else if (!"None".equalsIgnoreCase(swaggerAuthorizationConfiguration.getType())) { |
54 | | - builder.securitySchemes(Collections.singletonList(swaggerAuthorizationConfiguration.apiKey())); |
55 | | - } |
56 | | - |
57 | | - // 要忽略的参数类型 |
58 | | - Class<?>[] array = new Class[swaggerProperties.getIgnoredParameterTypes().size()]; |
59 | | - Class<?>[] ignoredParameterTypes = swaggerProperties.getIgnoredParameterTypes().toArray(array); |
60 | | - builder.ignoredParameterTypes(ignoredParameterTypes); |
61 | | - |
62 | | - // 设置全局参数 |
63 | | - if (swaggerProperties.getGlobalOperationParameters() != null) { |
64 | | - builder.globalRequestParameters(globalRequestParameters(swaggerProperties)); |
| 58 | + public void createSpringFoxRestApi() { |
| 59 | + BeanDefinitionRegistry beanRegistry = (BeanDefinitionRegistry)beanFactory; |
| 60 | + |
| 61 | + // 没有分组 |
| 62 | + if (swaggerProperties.getDocket().size() == 0) { |
| 63 | + String beanName = BEAN_NAME + "default"; |
| 64 | + BeanDefinition beanDefinition4Group = new GenericBeanDefinition(); |
| 65 | + beanDefinition4Group.getConstructorArgumentValues().addIndexedArgumentValue(0, DocumentationType.OAS_30); |
| 66 | + beanDefinition4Group.setBeanClassName(Docket.class.getName()); |
| 67 | + beanDefinition4Group.setRole(BeanDefinition.ROLE_SUPPORT); |
| 68 | + beanRegistry.registerBeanDefinition(beanName, beanDefinition4Group); |
| 69 | + |
| 70 | + Docket docket4Group = (Docket)beanFactory.getBean(beanName); |
| 71 | + ApiInfo apiInfo = apiInfo(swaggerProperties); |
| 72 | + docket4Group.host(swaggerProperties.getHost()).apiInfo(apiInfo).select() |
| 73 | + .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) |
| 74 | + .paths(paths(swaggerProperties.getBasePath(), swaggerProperties.getExcludePath())).build(); |
| 75 | + return; |
65 | 76 | } |
66 | 77 |
|
67 | | - // 需要生成文档的接口目标配置 |
68 | | - Docket docket = builder.select() |
69 | | - // 通过扫描包选择接口 |
70 | | - .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) |
71 | | - // 通过路径匹配选择接口 |
72 | | - .paths(paths(swaggerProperties)) |
| 78 | + for (Map.Entry<String, SwaggerProperties.DocketInfo> entry : swaggerProperties.getDocket().entrySet()) { |
| 79 | + String groupName = entry.getKey(); |
| 80 | + SwaggerProperties.DocketInfo docketInfo = entry.getValue(); |
| 81 | + String beanName = BEAN_NAME + groupName; |
| 82 | + |
| 83 | + ApiInfo apiInfo = new ApiInfoBuilder() |
| 84 | + .title(docketInfo.getTitle().isEmpty() ? swaggerProperties.getTitle() : docketInfo.getTitle()) |
| 85 | + .description(docketInfo.getDescription().isEmpty() ? swaggerProperties.getDescription() |
| 86 | + : docketInfo.getDescription()) |
| 87 | + .version(docketInfo.getVersion().isEmpty() ? swaggerProperties.getVersion() : docketInfo.getVersion()) |
| 88 | + .license(docketInfo.getLicense().isEmpty() ? swaggerProperties.getLicense() : docketInfo.getLicense()) |
| 89 | + .licenseUrl(docketInfo.getLicenseUrl().isEmpty() ? swaggerProperties.getLicenseUrl() |
| 90 | + : docketInfo.getLicenseUrl()) |
| 91 | + .contact(new Contact( |
| 92 | + docketInfo.getContact().getName().isEmpty() ? swaggerProperties.getContact().getName() |
| 93 | + : docketInfo.getContact().getName(), |
| 94 | + docketInfo.getContact().getUrl().isEmpty() ? swaggerProperties.getContact().getUrl() |
| 95 | + : docketInfo.getContact().getUrl(), |
| 96 | + docketInfo.getContact().getEmail().isEmpty() ? swaggerProperties.getContact().getEmail() |
| 97 | + : docketInfo.getContact().getEmail())) |
| 98 | + .termsOfServiceUrl(docketInfo.getTermsOfServiceUrl().isEmpty() |
| 99 | + ? swaggerProperties.getTermsOfServiceUrl() : docketInfo.getTermsOfServiceUrl()) |
73 | 100 | .build(); |
74 | 101 |
|
75 | | - return docket; |
| 102 | + // base-path处理 |
| 103 | + // 当没有配置任何path的时候,解析/** |
| 104 | + if (docketInfo.getBasePath().isEmpty()) { |
| 105 | + docketInfo.getBasePath().add("/**"); |
| 106 | + } |
| 107 | + |
| 108 | + List<Predicate<String>> basePath = new ArrayList<>(); |
| 109 | + for (String path : docketInfo.getBasePath()) { |
| 110 | + basePath.add(PathSelectors.ant(path)); |
| 111 | + } |
| 112 | + |
| 113 | + // exclude-path处理 |
| 114 | + List<Predicate<String>> excludePath = new ArrayList<>(); |
| 115 | + for (String path : docketInfo.getExcludePath()) { |
| 116 | + excludePath.add(PathSelectors.ant(path)); |
| 117 | + } |
| 118 | + |
| 119 | + BeanDefinition beanDefinition4Group = new GenericBeanDefinition(); |
| 120 | + beanDefinition4Group.getConstructorArgumentValues().addIndexedArgumentValue(0, DocumentationType.OAS_30); |
| 121 | + beanDefinition4Group.setBeanClassName(Docket.class.getName()); |
| 122 | + beanDefinition4Group.setRole(BeanDefinition.ROLE_SUPPORT); |
| 123 | + beanRegistry.registerBeanDefinition(beanName, beanDefinition4Group); |
| 124 | + |
| 125 | + Docket docket4Group = (Docket)beanFactory.getBean(beanName); |
| 126 | + docket4Group.groupName(groupName).host(docketInfo.getBasePackage()).apiInfo(apiInfo).select() |
| 127 | + .apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage())) |
| 128 | + .paths(paths(docketInfo.getBasePath(), docketInfo.getExcludePath())).build(); |
| 129 | + } |
76 | 130 | } |
77 | 131 |
|
78 | 132 | /** |
79 | 133 | * 全局请求参数 |
80 | 134 | * |
81 | | - * @param swaggerProperties {@link SwaggerProperties} |
| 135 | + * @param swaggerProperties |
| 136 | + * {@link SwaggerProperties} |
82 | 137 | * @return RequestParameter {@link RequestParameter} |
83 | 138 | */ |
84 | 139 | private List<RequestParameter> globalRequestParameters(SwaggerProperties swaggerProperties) { |
85 | | - return swaggerProperties.getGlobalOperationParameters().stream().map(param -> new RequestParameterBuilder() |
86 | | - .name(param.getName()) |
87 | | - .description(param.getDescription()) |
88 | | - .in(param.getParameterType()) |
89 | | - .required(param.getRequired()) |
| 140 | + return swaggerProperties.getGlobalOperationParameters().stream() |
| 141 | + .map(param -> new RequestParameterBuilder().name(param.getName()).description(param.getDescription()) |
| 142 | + .in(param.getParameterType()).required(param.getRequired()) |
90 | 143 | .query(q -> q.defaultValue(param.getModelRef())) |
91 | | - .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))) |
92 | | - .build()).collect(Collectors.toList()); |
| 144 | + .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))).build()) |
| 145 | + .collect(Collectors.toList()); |
93 | 146 | } |
94 | 147 |
|
95 | 148 | /** |
96 | 149 | * API接口路径选择 |
97 | 150 | * |
98 | | - * @param swaggerProperties |
99 | | - * @return |
| 151 | + * @param basePath |
| 152 | + * basePath |
| 153 | + * @param excludePath |
| 154 | + * excludePath |
| 155 | + * @return path |
100 | 156 | */ |
101 | 157 |
|
102 | | - private Predicate paths(SwaggerProperties swaggerProperties) { |
| 158 | + private Predicate paths(List<String> basePath, List<String> excludePath) { |
103 | 159 | // base-path处理 |
104 | 160 | // 当没有配置任何path的时候,解析/** |
105 | | - if (swaggerProperties.getBasePath().isEmpty()) { |
106 | | - swaggerProperties.getBasePath().add("/**"); |
| 161 | + if (basePath.isEmpty()) { |
| 162 | + basePath.add("/**"); |
107 | 163 | } |
108 | | - List<com.google.common.base.Predicate<String>> basePath = new ArrayList<>(); |
109 | | - for (String path : swaggerProperties.getBasePath()) { |
110 | | - basePath.add(PathSelectors.ant(path)); |
| 164 | + List<com.google.common.base.Predicate<String>> basePathList = new ArrayList<>(); |
| 165 | + for (String path : basePath) { |
| 166 | + basePathList.add(PathSelectors.ant(path)); |
111 | 167 | } |
112 | 168 |
|
113 | 169 | // exclude-path处理 |
114 | | - List<com.google.common.base.Predicate<String>> excludePath = new ArrayList<>(); |
115 | | - for (String path : swaggerProperties.getExcludePath()) { |
116 | | - excludePath.add(PathSelectors.ant(path)); |
| 170 | + List<com.google.common.base.Predicate<String>> excludePathList = new ArrayList<>(); |
| 171 | + for (String path : excludePath) { |
| 172 | + excludePathList.add(PathSelectors.ant(path)); |
117 | 173 | } |
118 | 174 |
|
119 | | - return Predicates.and( |
120 | | - Predicates.not(Predicates.or(excludePath)), |
121 | | - Predicates.or(basePath) |
122 | | - ); |
| 175 | + return Predicates.and(Predicates.not(Predicates.or(excludePathList)), Predicates.or(basePathList)); |
123 | 176 | } |
124 | 177 |
|
125 | 178 | /** |
126 | 179 | * API文档基本信息 |
127 | 180 | * |
128 | 181 | * @param swaggerProperties |
129 | | - * @return |
| 182 | + * swaggerProperties |
| 183 | + * @return apiInfo |
130 | 184 | */ |
131 | 185 | private ApiInfo apiInfo(SwaggerProperties swaggerProperties) { |
132 | | - ApiInfo apiInfo = new ApiInfoBuilder() |
133 | | - .title(swaggerProperties.getTitle()) |
134 | | - .description(swaggerProperties.getDescription()) |
135 | | - .version(swaggerProperties.getVersion()) |
136 | | - .license(swaggerProperties.getLicense()) |
137 | | - .licenseUrl(swaggerProperties.getLicenseUrl()) |
138 | | - .contact(new Contact(swaggerProperties.getContact().getName(), |
139 | | - swaggerProperties.getContact().getUrl(), |
140 | | - swaggerProperties.getContact().getEmail())) |
141 | | - .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()) |
142 | | - .build(); |
143 | | - return apiInfo; |
| 186 | + return new ApiInfoBuilder().title(swaggerProperties.getTitle()).description(swaggerProperties.getDescription()) |
| 187 | + .version(swaggerProperties.getVersion()).license(swaggerProperties.getLicense()) |
| 188 | + .licenseUrl(swaggerProperties.getLicenseUrl()) |
| 189 | + .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), |
| 190 | + swaggerProperties.getContact().getEmail())) |
| 191 | + .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()).build(); |
144 | 192 | } |
145 | | - |
146 | | - |
147 | 193 | } |
0 commit comments