反射获取springmvc方法信息并写入DB

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component
public class OpenApiHelper {

    private static final String OPENAPI_PACKAGE = "com.umgsai.open.api";

    @SofaReference
    private OpenApiService openApiService;

    private Map<String, String> uriMethodMap = Maps.newHashMap();

    @PostConstruct
    public void initOpenApi() {
        Reflections methodReflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage(OPENAPI_PACKAGE))
                .setScanners(new MethodAnnotationsScanner()));

        Set<Method> methods = methodReflections.getMethodsAnnotatedWith(RequestMapping.class);

        List<OpenApi> openApiListInCode = Lists.newArrayList();
        for (Method method : methods) {
            //log.info(method.getName());
            //log.info(method.getClass().getCanonicalName());
            //log.info(method.getClass().getName());
            //method所在的类
            Class<?> controllerClass = method.getDeclaringClass();
            //log.info(controllerClass.getName());

            //参数类型
            Type[] parameterTypes = method.getParameterTypes();
            List<String> parameterTypeNameList = Lists.newArrayList();
            for (Type parameterType : parameterTypes) {
                parameterTypeNameList.add(parameterType.getTypeName());
            }
            Type returnType = method.getReturnType();
            
            //对应Modifier中定义的public private 。。。
            int modifiers = method.getModifiers();

            List<String> parameterNameList = Lists.newArrayList();
            
            //获取方法的参数名称
            LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
            String[] parameterNames = u.getParameterNames(method);
            for (int i = 0; i < parameterNames.length; i++) {
                parameterNameList.add(parameterNames[i]);
            }

            int parameterCount = method.getParameterCount();
            List<String> parameterList = Lists.newArrayList();
            for (int i = 0; i < parameterCount; i++) {
                parameterList.add(String.format("%s %s", parameterTypeNameList.get(i), parameterNameList.get(i)));
            }

            //public java.lang.Object com.umgsai.open.api.controller.ContainerApiController.deleteContainer(long id)
            String methodName = String.format("%s %s %s.%s(%s)", Modifier.toString(modifiers), ((Class) returnType).getName(),
                    controllerClass.getName(), method.getName(), Joiner.on(",").join(parameterList));

            RequestMapping controllerRequestMappingAnnotation = controllerClass.getAnnotation(RequestMapping.class);
            String[] controllerRequestMapping = controllerRequestMappingAnnotation.value();
            if (controllerRequestMapping.length > 1) {
                throw new RuntimeException(String.format("Controller上不允许配置多个RequestMapping注解!方法名:%s", controllerClass.getName()));
            }

            RequestMapping methodRequestMappingAnnotation = method.getAnnotation(RequestMapping.class);
            String[] methodRequestMapping = methodRequestMappingAnnotation.value();
            if (methodRequestMapping.length > 1) {
                throw new RuntimeException(String.format("方法上不允许配置多个RequestMapping注解!方法名:%s", methodName));
            }
            StringBuilder uriBuilder = new StringBuilder();
            if (controllerRequestMapping.length == 1) {
                uriBuilder.append("/");
                String[] controllerUris = StringUtils.split(controllerRequestMapping[0], "/");
                uriBuilder.append(Joiner.on("/").join(Arrays.asList(controllerUris)));
            }
            if (methodRequestMapping.length == 1) {
                uriBuilder.append("/");
                String[] methodUris = StringUtils.split(methodRequestMapping[0], "/");
                uriBuilder.append(Joiner.on("/").join(Arrays.asList(methodUris)));
            }
            String uri = uriBuilder.toString();
            //log.info(methodName);
            //log.info(uri);
            uriMethodMap.put(uri, methodName);

            MethodComment methodComment = method.getAnnotation(MethodComment.class);
            String methodCommentValue = "";
            if (methodComment != null) {
                methodCommentValue = methodComment.value();
            }

            String[] strs = StringUtils.split(controllerClass.getName(), ".");
            String apiControllerName = strs[strs.length - 1];
            openApiListInCode.add(new OpenApi(uri, methodName, methodCommentValue, apiControllerName, method.getName()));
        }
        openApiService.updateOpenApi(openApiListInCode);
        log.info(JSON.toJSONString(uriMethodMap));
    }
}

//使用注解配置方法的注释信息

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodComment {

    String value() default "";
}

对应的controller中的方法


    @ResponseBody
    @MethodComment("分页查询容器列表")
    @RequestMapping(value = "/queryContainerList.json", method = RequestMethod.GET)
    public Object queryContainerList(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
                                     @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
        DataResult<PageInfo<Container>> dataResult = containerService.queryByPage(pageNum, pageSize);
        return dataResult;
    }
@Slf4j
@Component
@SofaService
public class OpenApiServiceImpl implements OpenApiService {

    @AutoWired
    private OpenApiDao openApiDao;

    @Override
    public DataResult updateOpenApi(List<OpenApi> openApiListInCode) {
        if (CollectionUtils.isEmpty(openApiListInCode)) {
            return DataResult.successResult("openApiListInCode为空");
        }
        Map<String, OpenApi> map = Maps.newHashMap();
        for (OpenApi openApi : openApiListInCode) {
            map.put(openApi.getApiUri(), openApi);
        }
        List<OpenApi> openApiListInDb = openApiDao.queryAll();

        Set<String> uriSetInDb = Sets.newHashSet();
        for (OpenApi openApiInDb : openApiListInDb) {
            uriSetInDb.add(openApiInDb.getApiUri());
            OpenApi openApiInCode = map.get(openApiInDb.getApiUri());
            if (openApiInCode == null) {
                //需要删除DB里的记录
                openApiDao.delete(openApiInDb.getId());
                continue;
            }
            if (openApiInCode.equals(openApiInDb)) {
                //DB里的记录和代码中的数据一致,不需要操作
                continue;
            }
            //DB里的记录和代码中的数据不一致,需要更新,以代码中的数据为准
            openApiInDb.setApiUri(openApiInCode.getApiUri());
            openApiInDb.setApiMethod(openApiInCode.getApiMethod());
            openApiInDb.setApiComment(openApiInCode.getApiComment());
            openApiDao.update(openApiInDb);
        }

        for (OpenApi openApiInCode : openApiListInCode) {
            //如果代码中存在 但是DB中不存在,则需要添加到DB中
            if (!uriSetInDb.contains(openApiInCode.getApiUri())) {
                openApiDao.insert(new OpenApi(openApiInCode.getApiUri(), openApiInCode.getApiMethod(), openApiInCode.getApiComment(),
                        openApiInCode.getApiControllerName(), openApiInCode.getApiMethodName()));
            }
        }
        return DataResult.successResult();
    }
}

需要依赖的jar包

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.11</version>
</dependency>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值