package com.qianwen.core.scanner.modular; import cn.hutool.core.util.StrUtil; import io.swagger.annotations.ApiOperation; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.qianwen.core.scanner.config.properties.ScannerProperties; import com.qianwen.core.scanner.modular.annotation.DeleteResource; import com.qianwen.core.scanner.modular.annotation.GetResource; import com.qianwen.core.scanner.modular.annotation.PostResource; import com.qianwen.core.scanner.modular.annotation.PutResource; import com.qianwen.core.scanner.modular.constants.ConfigPrefixConstants; import com.qianwen.core.scanner.modular.factory.ApiResourceFactory; import com.qianwen.core.scanner.modular.model.ResourceDefinition; import com.qianwen.core.scanner.modular.stereotype.ApiResource; import com.qianwen.core.scanner.modular.util.AopTargetUtils; import com.qianwen.core.tool.utils.CollectionUtil; import com.qianwen.core.tool.utils.Func; import com.qianwen.core.tool.utils.StringUtil; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /* loaded from: blade-starter-scanner-9.3.0.0-SNAPSHOT.jar:org/springblade/core/scanner/modular/ApiResourceScanner.class */ public class ApiResourceScanner implements BeanPostProcessor { private static final Logger log = LoggerFactory.getLogger(ApiResourceScanner.class); private ApiResourceFactory apiResourceFactory; private ScannerProperties scannerProperties; public ApiResourceScanner(ApiResourceFactory apiResourceFactory, ScannerProperties scannerProperties, String springApplicationName) { this.apiResourceFactory = apiResourceFactory; this.scannerProperties = scannerProperties; } public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (!this.scannerProperties.getOpen().booleanValue()) { return bean; } if ("oauth2ClientContext".equals(beanName)) { return bean; } Object aopTarget = AopTargetUtils.getTarget(bean); if (aopTarget == null) { aopTarget = bean; } Class clazz = aopTarget.getClass(); boolean controllerFlag = getControllerFlag(clazz); if (!controllerFlag) { return bean; } List apiResources = doScan(clazz); persistApiResources(apiResources); return bean; } private boolean getControllerFlag(Class clazz) { Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { if (RestController.class.equals(annotation.annotationType()) || Controller.class.equals(annotation.annotationType())) { return true; } } return false; } private List doScan(Class clazz) { ApiResource classApiAnnotation = (ApiResource) clazz.getAnnotation(ApiResource.class); if (classApiAnnotation != null) { if (StrUtil.isEmpty(classApiAnnotation.code())) { String className = clazz.getSimpleName(); int controllerIndex = className.indexOf("Controller"); if (controllerIndex == -1) { throw new IllegalArgumentException("controller class name is not illegal, it should end with Controller!"); } String code = className.substring(0, controllerIndex); this.apiResourceFactory.bindResourceName(StrUtil.toUnderlineCase(code), classApiAnnotation.name()); } else { this.apiResourceFactory.bindResourceName(StrUtil.toUnderlineCase(classApiAnnotation.code()), classApiAnnotation.name()); } } ArrayList apiResources = new ArrayList<>(); Method[] declaredMethods = clazz.getDeclaredMethods(); if (declaredMethods != null && declaredMethods.length > 0) { for (Method declaredMethod : declaredMethods) { Annotation apiResource = (ApiResource) declaredMethod.getAnnotation(ApiResource.class); Annotation getResource = (GetResource) declaredMethod.getAnnotation(GetResource.class); Annotation postResource = (PostResource) declaredMethod.getAnnotation(PostResource.class); Annotation putResource = (PutResource) declaredMethod.getAnnotation(PutResource.class); Annotation deleteResource = (DeleteResource) declaredMethod.getAnnotation(DeleteResource.class); Annotation annotation = null; if (apiResource != null) { annotation = apiResource; } if (getResource != null) { annotation = getResource; } if (postResource != null) { annotation = postResource; } if (putResource != null) { annotation = putResource; } if (deleteResource != null) { annotation = deleteResource; } if (annotation != null) { ResourceDefinition definition = createDefinition(clazz, declaredMethod, annotation); apiResources.add(definition); log.debug("扫描到资源: " + definition); } } } return apiResources; } private void persistApiResources(List apiResources) { this.apiResourceFactory.registerDefinition(apiResources); } private ResourceDefinition createDefinition(Class clazz, Method method, Annotation apiResource) { ApiOperation annotation; ResourceDefinition resourceDefinition = new ResourceDefinition(); resourceDefinition.setClassName(clazz.getSimpleName()); resourceDefinition.setMethodName(method.getName()); String className = resourceDefinition.getClassName(); int controllerIndex = className.indexOf("Controller"); if (controllerIndex == -1) { throw new IllegalArgumentException("controller class name is not illegal, it should end with Controller!"); } String modular = className.substring(0, controllerIndex); resourceDefinition.setControllerCode(modular); ApiResource classApiAnnotation = (ApiResource) clazz.getAnnotation(ApiResource.class); if (classApiAnnotation != null && Func.isNotEmpty(classApiAnnotation.moduleCode())) { resourceDefinition.setModuleCode(classApiAnnotation.moduleCode()); } String code = (String) invokeAnnotationMethod(apiResource, "code", String.class); if (StrUtil.isEmpty(code)) { resourceDefinition.setCode(StrUtil.toUnderlineCase(modular) + this.scannerProperties.getLinkSymbol() + StrUtil.toUnderlineCase(method.getName())); } else { resourceDefinition.setCode(StrUtil.toUnderlineCase(modular) + this.scannerProperties.getLinkSymbol() + StrUtil.toUnderlineCase(code)); } String name = (String) invokeAnnotationMethod(apiResource, "name", String.class); String[] path = (String[]) invokeAnnotationMethod(apiResource, "path", String[].class); String[] value = (String[]) invokeAnnotationMethod(apiResource, "value", String[].class); RequestMethod[] requestMethods = (RequestMethod[]) invokeAnnotationMethod(apiResource, "method", RequestMethod[].class); Boolean buttonFlag = (Boolean) invokeAnnotationMethod(apiResource, "buttonFlag", Boolean.class); resourceDefinition.setName(name); resourceDefinition.setButtonFlag(buttonFlag); if (CollectionUtil.isNotEmpty(Arrays.asList(path))) { if (!path[0].startsWith("/") && Func.isNotEmpty(path[0])) { path[0] = "/" + path[0]; } resourceDefinition.setUrl(getControllerClassRequestPath(clazz) + path[0].replaceAll("\\{[^}]*\\}", "*")); } else if (CollectionUtil.isNotEmpty(Arrays.asList(value))) { if (!value[0].startsWith("/") && Func.isNotEmpty(value[0])) { value[0] = "/" + value[0]; } resourceDefinition.setUrl(getControllerClassRequestPath(clazz) + value[0].replaceAll("\\{[^}]*\\}", "*")); } else { resourceDefinition.setUrl(getControllerClassRequestPath(clazz)); } List splitPath = StringUtil.splitTrim(resourceDefinition.getUrl(), ConfigPrefixConstants.SPLIT_CHAR.charValue()); if (splitPath.size() > 1 && Func.isEmpty(resourceDefinition.getModuleCode())) { resourceDefinition.setModuleCode(splitPath.get(0)); } if (Func.isEmpty(resourceDefinition.getModuleCode())) { resourceDefinition.setModuleCode(ConfigPrefixConstants.DEFAULT_MODULE_CODE); } String methodNames = ""; for (RequestMethod requestMethod : requestMethods) { methodNames = methodNames + requestMethod.name() + ","; } resourceDefinition.setHttpMethod(StrUtil.removeSuffix(methodNames, ",")); resourceDefinition.setCreateTime(new Date()); if (Func.isEmpty(resourceDefinition.getName()) && (annotation = method.getAnnotation(ApiOperation.class)) != null) { resourceDefinition.setName(annotation.value()); } return resourceDefinition; } private String getControllerClassRequestPath(Class clazz) { String result; ApiResource controllerRequestMapping = (ApiResource) clazz.getDeclaredAnnotation(ApiResource.class); if (controllerRequestMapping == null) { result = ""; } else { String[] paths = controllerRequestMapping.path(); String[] values = controllerRequestMapping.value(); if (paths.length > 0) { result = paths[0]; } else if (values.length > 0) { result = values[0]; } else { result = ""; } } return "/" + result; } private T invokeAnnotationMethod(Annotation apiResource, String methodName, Class resultType) { try { Class annotationType = apiResource.annotationType(); Method method = annotationType.getMethod(methodName, new Class[0]); return (T) method.invoke(apiResource, new Object[0]); } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { log.error("扫描api资源时出错!", e); throw new RuntimeException("扫描api资源时出错!"); } } }