docs 补充项目注释

This commit is contained in:
AprilWind
2026-06-01 11:50:59 +08:00
parent 941c0b9032
commit 107d3326b4
66 changed files with 1079 additions and 110 deletions
@@ -37,14 +37,33 @@ import java.util.stream.Stream;
@RequiredArgsConstructor
public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApiCustomizer {
/**
* JavaDoc 提供器。
*/
private final Optional<JavadocProvider> javadocProvider;
/**
* SpringDoc 属性解析工具。
*/
private final PropertyResolverUtils propertyResolverUtils;
/**
* 已解析的 OpenAPI 顶层标签缓存。
*/
private final Map<String, Tag> tags = new ConcurrentHashMap<>();
/**
* 已被类 JavaDoc 替换的自动标签名称集合。
*/
private final Set<String> replacedAutoTagNames = ConcurrentHashMap.newKeySet();
/**
* 自定义接口操作的标签信息。
*
* @param operation OpenAPI 操作对象
* @param handlerMethod 处理器方法
* @return 自定义后的 OpenAPI 操作对象
*/
@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
Class<?> beanType = handlerMethod.getBeanType();
@@ -73,6 +92,11 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
return operation;
}
/**
* 自定义 OpenAPI 顶层标签集合。
*
* @param openApi OpenAPI 文档对象
*/
@Override
public void customise(OpenAPI openApi) {
if (!CollectionUtils.isEmpty(openApi.getTags()) && !CollectionUtils.isEmpty(replacedAutoTagNames)) {
@@ -87,6 +111,12 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
});
}
/**
* 获取 Controller 类上的 Swagger 标签注解。
*
* @param beanType Controller 类型
* @return 标签注解列表
*/
private List<io.swagger.v3.oas.annotations.tags.Tag> getClassTags(Class<?> beanType) {
Set<Tags> tagsSet = AnnotatedElementUtils.findAllMergedAnnotations(beanType, Tags.class);
Set<io.swagger.v3.oas.annotations.tags.Tag> mergedTags = tagsSet.stream()
@@ -96,6 +126,12 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
return new ArrayList<>(mergedTags);
}
/**
* 将类级 Swagger 标签追加到接口操作与顶层标签缓存。
*
* @param operation OpenAPI 操作对象
* @param classTags 类级标签注解
*/
private void addAnnotationTags(Operation operation, List<io.swagger.v3.oas.annotations.tags.Tag> classTags) {
classTags.stream()
.map(io.swagger.v3.oas.annotations.tags.Tag::name)
@@ -113,6 +149,12 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
}));
}
/**
* 获取类 JavaDoc 第一行作为标签名称。
*
* @param beanType Controller 类型
* @return 标签名称,未配置 JavaDoc 时返回 null
*/
private String getClassJavadocTagName(Class<?> beanType) {
if (javadocProvider.isEmpty()) {
return null;
@@ -126,10 +168,23 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
return lines.stream().filter(StringUtils::isNotBlank).findFirst().orElse(null);
}
/**
* 判断当前操作是否可以使用类 JavaDoc 标签替换默认标签。
*
* @param operation OpenAPI 操作对象
* @param autoTagName SpringDoc 自动生成的标签名
* @return true 可以替换 false 不替换
*/
private boolean shouldUseClassJavadocTag(Operation operation, String autoTagName) {
return CollectionUtils.isEmpty(operation.getTags()) || operation.getTags().contains(autoTagName);
}
/**
* 为接口操作追加标签。
*
* @param operation OpenAPI 操作对象
* @param tagName 标签名称
*/
private void addOperationTag(Operation operation, String tagName) {
if (operation.getTags() == null) {
operation.setTags(new ArrayList<>());
@@ -139,6 +194,12 @@ public class ClassTagOperationCustomizer implements OperationCustomizer, OpenApi
}
}
/**
* 从接口操作中移除指定标签。
*
* @param operation OpenAPI 操作对象
* @param tagName 标签名称
*/
private void removeOperationTag(Operation operation, String tagName) {
if (!CollectionUtils.isEmpty(operation.getTags())) {
operation.getTags().removeIf(item -> Objects.equals(item, tagName));
@@ -20,10 +20,23 @@ import java.util.Optional;
@RequiredArgsConstructor
public class JavadocOperationCustomizer implements OperationCustomizer {
/**
* JavaDoc 提供器。
*/
private final Optional<JavadocProvider> javadocProvider;
/**
* JavaDoc 扩展解析器列表。
*/
private final List<JavadocResolver> javadocResolvers;
/**
* 自定义接口操作的 JavaDoc 描述。
*
* @param operation OpenAPI 操作对象
* @param handlerMethod 处理器方法
* @return 自定义后的 OpenAPI 操作对象
*/
@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
javadocProvider.ifPresent(provider -> {
@@ -18,27 +18,63 @@ import java.util.function.Supplier;
*/
public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResolver {
/**
* 最高优先级。
*/
public static final int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
/**
* 最低优先级。
*/
public static final int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
/**
* 元数据提供者。
*/
private final Supplier<M> metadataProvider;
/**
* 解析器排序值。
*/
private final int order;
/**
* 构造元数据 Javadoc 解析器。
*
* @param metadataProvider 元数据提供者
*/
public AbstractMetadataJavadocResolver(Supplier<M> metadataProvider) {
this(metadataProvider, LOWEST_PRECEDENCE);
}
/**
* 构造带排序值的元数据 Javadoc 解析器。
*
* @param metadataProvider 元数据提供者
* @param order 排序值
*/
public AbstractMetadataJavadocResolver(Supplier<M> metadataProvider, int order) {
this.metadataProvider = metadataProvider;
this.order = order;
}
/**
* 获取解析器排序值。
*
* @return 排序值
*/
@Override
public int getOrder() {
return order;
}
/**
* 使用当前元数据解析接口文档描述。
*
* @param handlerMethod 处理器方法
* @param operation Swagger Operation 实例
* @return 解析后的 Javadoc 内容
*/
@Override
public String resolve(HandlerMethod handlerMethod, Operation operation) {
return resolve(handlerMethod, operation, metadataProvider.get());
@@ -157,6 +193,13 @@ public abstract class AbstractMetadataJavadocResolver<M> implements JavadocResol
return AnnotationUtil.getAnnotationValueMap(handlerMethod.getMethod(), annotationClass);
}
/**
* 获取指定元素上的注解属性映射。
*
* @param annotatedElement 被注解元素
* @param annotationClass 注解类型
* @return 注解属性映射
*/
private Map<String, Object> getAnnotationValueMap(AnnotatedElement annotatedElement, Class<? extends Annotation> annotationClass) {
return AnnotationUtil.getAnnotationValueMap(annotatedElement, annotationClass);
}
@@ -27,15 +27,49 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
*/
public static final Supplier<SaTokenSecurityMetadata> DEFAULT_METADATA_PROVIDER = SaTokenSecurityMetadata::new;
/**
* Sa-Token 注解包名。
*/
private static final String BASE_CLASS_NAME = "cn.dev33.satoken.annotation";
/**
* Sa-Token 角色校验注解类名。
*/
private static final String SA_CHECK_ROLE_CLASS_NAME = BASE_CLASS_NAME + ".SaCheckRole";
/**
* Sa-Token 权限校验注解类名。
*/
private static final String SA_CHECK_PERMISSION_CLASS_NAME = BASE_CLASS_NAME + ".SaCheckPermission";
/**
* Sa-Token 忽略校验注解类名。
*/
private static final String SA_IGNORE_CLASS_NAME = BASE_CLASS_NAME + ".SaIgnore";
/**
* Sa-Token 登录校验注解类名。
*/
private static final String SA_CHECK_LOGIN_NAME = BASE_CLASS_NAME + ".SaCheckLogin";
/**
* Sa-Token 角色校验注解类型。
*/
private static final Class<? extends Annotation> SA_CHECK_ROLE_CLASS;
/**
* Sa-Token 权限校验注解类型。
*/
private static final Class<? extends Annotation> SA_CHECK_PERMISSION_CLASS;
/**
* Sa-Token 忽略校验注解类型。
*/
private static final Class<? extends Annotation> SA_IGNORE_CLASS;
/**
* Sa-Token 登录校验注解类型。
*/
private static final Class<? extends Annotation> SA_CHECK_LOGIN_CLASS;
@@ -50,6 +84,9 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
}
}
/**
* 构造 Sa-Token 权限解析器。
*/
public SaTokenAnnotationMetadataJavadocResolver() {
this(DEFAULT_METADATA_PROVIDER);
}