扫描项目代码结构

----------------------------------------------------------------1原版------------------------------------------------------------------------------------

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * Controller + 实体类 统计导出模板
 */
@Data
public class ControllerEntityExcel {

    @ExcelProperty(value = "接口模块名称", index = 0)
    private String moduleName;

    @ExcelProperty(value = "Controller接口前缀", index = 1)
    private String requestMappingPath;

    @ExcelProperty(value = "Controller名称", index = 2)
    private String controllerName;

    @ExcelProperty(value = "Controller全类名", index = 3)
    private String controllerClass;

    @ExcelProperty(value = "关联实体类", index = 4)
    private String entityName;

    @ExcelProperty(value = "对应数据库表", index = 5)
    private String tableName;
}

  

import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

public class ControllerEntityStats {

    // ================== 改成你的项目包名 ==================
    private static final String BASE_PACKAGE = "xxx";
    // ====================================================

    private static Map<String, Class<?>> entityClassMap = new HashMap<>();
    private static Set<String> entitySimpleNames = new HashSet<>();

    public static List<ControllerEntityExcel> scan() {
        List<ControllerEntityExcel> result = new ArrayList<>();
        scanMyBatisPlusEntities();
        Set<Class<?>> controllers = scanControllers();

        for (Class<?> controller : controllers) {
            // 1. 模块名称
            String moduleName = "无模块";
            if (controller.isAnnotationPresent(Tag.class)) {
                moduleName = controller.getAnnotation(Tag.class).name();
            }

            // 2. 请求路径
            String reqPath = "无";
            if (controller.isAnnotationPresent(RequestMapping.class)) {
                String[] paths = controller.getAnnotation(RequestMapping.class).value();
                if (paths.length > 0) {
                    reqPath = String.join(",", paths);
                }
            }

            // 3. 智能匹配关联实体(终极增强)
            Set<String> relatedEntities = intelligentMatchEntity(controller);

            if (relatedEntities.isEmpty()) {
                ControllerEntityExcel excel = new ControllerEntityExcel();
                excel.setModuleName(moduleName);
                excel.setRequestMappingPath(reqPath);
                excel.setControllerName(controller.getSimpleName());
                excel.setControllerClass(controller.getName());
                excel.setEntityName("无");
                excel.setTableName("无");
                result.add(excel);
            } else {
                for (String entityName : relatedEntities) {
                    ControllerEntityExcel excel = new ControllerEntityExcel();
                    excel.setModuleName(moduleName);
                    excel.setRequestMappingPath(reqPath);
                    excel.setControllerName(controller.getSimpleName());
                    excel.setControllerClass(controller.getName());
                    excel.setEntityName(entityName);
                    excel.setTableName(getTableName(entityName));
                    result.add(excel);
                }
            }
        }
        return result;
    }

    // ========================= 核心:智能匹配实体(支持Controller名匹配实体名) =========================
    private static Set<String> intelligentMatchEntity(Class<?> controller) {
        Set<String> matchSet = new HashSet<>();

        // 方式1:深度解析方法返回值/参数(泛型全支持)
        deepScanMethodEntities(controller, matchSet);

        // 方式2:按 Controller 名字智能匹配实体类(UserCollectController → UserCollect)
        String controllerName = controller.getSimpleName();
        String entityCandidate = controllerName.replace("Controller", "");
        if (entitySimpleNames.contains(entityCandidate)) {
            matchSet.add(entityCandidate);
        }

        return matchSet;
    }

    private static void deepScanMethodEntities(Class<?> controller, Set<String> matchSet) {
        for (Method method : controller.getDeclaredMethods()) {
            extractRealType(method.getGenericReturnType(), matchSet);
            for (Type type : method.getGenericParameterTypes()) {
                extractRealType(type, matchSet);
            }
        }
    }

    private static void extractRealType(Type type, Set<String> realEntities) {
        if (type instanceof ParameterizedType) {
            Type[] args = ((ParameterizedType) type).getActualTypeArguments();
            for (Type t : args) {
                extractRealType(t, realEntities);
            }
        } else if (type instanceof Class) {
            // JDK8 传统写法,无报错
            Class<?> clazz = (Class<?>) type;

            if (entitySimpleNames.contains(clazz.getSimpleName())) {
                realEntities.add(clazz.getSimpleName());
            }

            // 兼容 DTO/VO/BO
            String className = clazz.getSimpleName();
            if (className.endsWith("DTO") || className.endsWith("VO") || className.endsWith("BO")) {
                String entityName = className.replaceAll("(DTO|VO|BO)$", "");
                if (entitySimpleNames.contains(entityName)) {
                    realEntities.add(entityName);
                }
            }
        }
    }

    // 扫描 MyBatis-Plus @TableName 实体
    private static void scanMyBatisPlusEntities() {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(TableName.class));

        Set<Class<?>> set = new HashSet<>();
        for (BeanDefinition bd : scanner.findCandidateComponents(BASE_PACKAGE)) {
            try {
                Class<?> clazz = Class.forName(bd.getBeanClassName());
                entityClassMap.put(clazz.getSimpleName(), clazz);
                entitySimpleNames.add(clazz.getSimpleName());
            } catch (Exception ignored) {}
        }
    }

    // 扫描 Controller
    private static Set<Class<?>> scanControllers() {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
        scanner.addIncludeFilter(new AnnotationTypeFilter(Controller.class));

        Set<Class<?>> set = new HashSet<>();
        for (BeanDefinition bd : scanner.findCandidateComponents(BASE_PACKAGE)) {
            try {
                set.add(Class.forName(bd.getBeanClassName()));
            } catch (Exception ignored) {}
        }
        return set;
    }

    // 获取表名
    private static String getTableName(String entitySimpleName) {
        Class<?> clazz = entityClassMap.get(entitySimpleName);
        if (clazz == null) {
            return "无表名";
        }
        TableName tableName = clazz.getAnnotation(TableName.class);
        return tableName != null ? tableName.value() : clazz.getSimpleName();
    }
}
import com.alibaba.excel.EasyExcel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/admin/stats")
public class StatsExportController  {

    /**
     * 导出 Controller 与 实体类 统计 Excel
     */
    @GetMapping("/export-controller-entity")
    public void export(HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("Controller_实体类统计.xlsx", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);

        // 核心统计
        List<ControllerEntityExcel> list = ControllerEntityStats.scan();

        // 写出到浏览器
        EasyExcel.write(response.getOutputStream(), ControllerEntityExcel.class)
                .sheet("Controller统计")
                .doWrite(list);
    }
}

  

----------------------------------------------------------------2新版------------------------------------------------------------------------------------

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
//汇总版:http://127.0.0.1:7011/admin/stats/export-final-7column
//明细版:http://127.0.0.1:7011/admin/stats/export-detail-7column

@Data
public class Detail7ColumnExcel {

    @ExcelProperty(value = "接口模块名称", index = 0)
    private String moduleName;

    @ExcelProperty(value = "Controller接口前缀", index = 1)
    private String controllerBasePath;

    @ExcelProperty(value = "Controller名称", index = 2)
    private String controllerName;

    @ExcelProperty(value = "Controller全类名", index = 3)
    private String controllerFullClassName;

    @ExcelProperty(value = "Service名称", index = 4)
    private String serviceName;

    @ExcelProperty(value = "引入Service名称", index = 5)
    private String nestedServiceName;

    @ExcelProperty(value = "关联实体类", index = 6)
    private String entityName;

    @ExcelProperty(value = "对应数据库表", index = 7)
    private String tableName;
}



import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class Final7ColumnExcel {

    @ExcelProperty(value = "接口模块名称", index = 0)
    private String moduleName;

    @ExcelProperty(value = "Controller接口前缀", index = 1)
    private String controllerBasePath;

    @ExcelProperty(value = "Controller名称", index = 2)
    private String controllerName;

    @ExcelProperty(value = "Controller全类名", index = 3)
    private String controllerFullClassName;

    @ExcelProperty(value = "Service名称", index = 4)
    private String serviceList;

    @ExcelProperty(value = "引入Service名称", index = 5)
    private String nestedServiceList;

    @ExcelProperty(value = "关联实体类", index = 6)
    private String entityList;

    @ExcelProperty(value = "对应数据库表", index = 7)
    private String tableList;
}

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/admin/stats")
public class Final7ColumnExportController {

    /**
     * 导出7列完整架构表
     */
    @GetMapping("/export-final-7column")
    public void exportFinal7Column(HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("微服务7列架构统计表.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        List<Final7ColumnExcel> dataList = Final7ColumnScanner.scan();

        EasyExcel.write(response.getOutputStream(), Final7ColumnExcel.class)
                .sheet("导出服务数据汇总")
                .doWrite(dataList);
    }

    /**
     * 明细版导出:一行一个 Service + 实体 + 表 完整组合
     */
    /*@GetMapping("/export-detail-7column")
    public void exportDetail7Column(HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("微服务7列架构明细表.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        List<Detail7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();

        EasyExcel.write(response.getOutputStream(), Detail7ColumnExcel.class)
                .sheet("7列架构明细")
                .doWrite(dataList);
    }*/

    @GetMapping("/export-detail-7column")
    public void exportDetail7Column(HttpServletResponse response) {
        try {
            // ========= 强制禁用缓存,防止断开连接 =========
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");

            String fileName = URLEncoder.encode("七列关系导出", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ExcelTypeEnum.XLSX.getValue());

            // ========= 获取数据(你现有的方法) =========
            //List<Final7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();
            List<Detail7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();

            // ========= 写入 Excel(不关闭流,交给Tomcat) =========
            EasyExcel.write(response.getOutputStream(), Final7ColumnExcel.class)
                    .excelType(ExcelTypeEnum.XLSX)
                    .autoCloseStream(false) // ✅ 关键:禁止自动关闭流
                    .sheet("导出服务数据明细")
                    .doWrite(dataList);

        } catch (Exception e) {
            // 忽略客户端断开异常,防止报错
            if (!e.getMessage().contains("Connection reset by peer") &&
                    !e.getMessage().contains("已建立的连接")) {
                e.printStackTrace();
            }
        }
    }
}




import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.Resource;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

public final class Final7ColumnScanner {

    private static final String BASE_PACKAGE = "xxx";
    private static final Map<String, Class<?>> ENTITY_MAP = new HashMap<>();
    private static final Set<String> ENTITY_SIMPLE_SET = new HashSet<>();

    public static List<Final7ColumnExcel> scan() {
        List<Final7ColumnExcel> resultList = new ArrayList<>();
        scanAllEntities();
        Set<Class<?>> controllerSet = scanAllControllers();

        for (Class<?> controllerCls : controllerSet) {
            String moduleName = getTagModuleName(controllerCls);
            String basePath = getClassRequestMapping(controllerCls);
            String controllerName = controllerCls.getSimpleName();
            String fullClassName = controllerCls.getName();

            Set<String> mainServices = getDirectServiceList(controllerCls);
            Set<String> allNested = new LinkedHashSet<>();
            Set<String> allEntities = new LinkedHashSet<>();

            // ====== 遍历主Service,收集 内部嵌套Service/Mapper + 实体 ======
            for (String s : mainServices) {
                Class<?> itf = findServiceInterface(controllerCls, s);
                if (itf == null) {
                    itf = getClassByName(s);
                }
                Set<String> nested = getInsideServiceAndMapper(itf);
                allNested.addAll(nested);

                // 解析主Service自身的实体
                String mainEnt = getEntityCommon(itf);
                if (mainEnt == null) {
                    mainEnt = s.replace("Service", "").replace("Impl", "");
                    if (mainEnt.startsWith("I")) mainEnt = mainEnt.substring(1);
                }
                if (ENTITY_SIMPLE_SET.contains(mainEnt)) {
                    allEntities.add(mainEnt);
                }

                // ====== 【关键】解析内部嵌套的 Mapper/Service 实体 ======
                for (String nestedName : nested) {
                    Class<?> nestedClazz = getClassByName(nestedName);
                    String nestedEnt = getEntityCommon(nestedClazz);
                    if (nestedEnt != null && ENTITY_SIMPLE_SET.contains(nestedEnt)) {
                        allEntities.add(nestedEnt);
                    }
                }
            }

            Final7ColumnExcel row = new Final7ColumnExcel();
            row.setModuleName(moduleName);
            row.setControllerBasePath(basePath);
            row.setControllerName(controllerName);
            row.setControllerFullClassName(fullClassName);
            row.setServiceList(String.join("、", mainServices));
            row.setNestedServiceList(String.join("、", allNested));
            row.setEntityList(String.join("、", allEntities));
            row.setTableList(getTableNames(allEntities));
            resultList.add(row);
        }
        return resultList;
    }

    public static List<Detail7ColumnExcel> scanDetail() {
        List<Detail7ColumnExcel> resultList = new ArrayList<>();
        scanAllEntities();
        Set<Class<?>> controllerSet = scanAllControllers();

        for (Class<?> controllerCls : controllerSet) {
            String moduleName = getTagModuleName(controllerCls);
            String basePath = getClassRequestMapping(controllerCls);
            String controllerName = controllerCls.getSimpleName();
            String fullClassName = controllerCls.getName();

            Set<String> mainServices = getDirectServiceList(controllerCls);
            if (mainServices.isEmpty()) {
                addEmpty(resultList, moduleName, basePath, controllerName, fullClassName);
                continue;
            }

            for (String mainService : mainServices) {
                Class<?> mainItf = findServiceInterface(controllerCls, mainService);
                if (mainItf == null) {
                    mainItf = getClassByName(mainService);
                }
                Set<String> insideList = getInsideServiceAndMapper(mainItf);

                // 【主Service自身】
                String mainEntity = getEntityCommon(mainItf);
                String mainTable = getTableNameByEntity(mainEntity);

                Detail7ColumnExcel mainRow = new Detail7ColumnExcel();
                mainRow.setModuleName(moduleName);
                mainRow.setControllerBasePath(basePath);
                mainRow.setControllerName(controllerName);
                mainRow.setControllerFullClassName(fullClassName);
                mainRow.setServiceName(mainService);
                mainRow.setNestedServiceName(mainService); // <-- 显示自身Service名称
                mainRow.setEntityName(mainEntity == null ? "" : mainEntity);
                mainRow.setTableName(mainTable == null ? "" : mainTable);
                resultList.add(mainRow);

                if (insideList.isEmpty()) {
                    Detail7ColumnExcel row = new Detail7ColumnExcel();
                    row.setModuleName(moduleName);
                    row.setControllerBasePath(basePath);
                    row.setControllerName(controllerName);
                    row.setControllerFullClassName(fullClassName);
                    row.setServiceName(mainService);
                    row.setNestedServiceName("无");
                    row.setEntityName(mainEntity == null ? "" : mainEntity);
                    row.setTableName(mainTable == null ? "" : mainTable);
                    resultList.add(row);
                } else {
                    // ==============================================
                    // 【核心修复】遍历内部的 Mapper,强制解析它的实体!
                    // ==============================================
                    for (String nested : insideList) {
                        Class<?> nestedClazz = getClassByName(nested);

                        // 【强制解析:不管Service有没有,都用Mapper自己的实体】
                        String entity = getEntityCommon(nestedClazz);
                        String table = getTableNameByEntity(entity);

                        Detail7ColumnExcel row = new Detail7ColumnExcel();
                        row.setModuleName(moduleName);
                        row.setControllerBasePath(basePath);
                        row.setControllerName(controllerName);
                        row.setControllerFullClassName(fullClassName);
                        row.setServiceName(mainService);
                        row.setNestedServiceName(nested);
                        row.setEntityName(entity == null ? "" : entity);
                        row.setTableName(table == null ? "" : table);
                        resultList.add(row);
                    }
                }
            }
        }
        return resultList;
    }

    private static Set<String> getDirectServiceList(Class<?> controllerCls) {
        Set<String> set = new LinkedHashSet<>();
        for (Field f : controllerCls.getDeclaredFields()) {
            if (f.isAnnotationPresent(javax.annotation.Resource.class) || f.isAnnotationPresent(Autowired.class)) {
                String name = f.getType().getSimpleName();
                if (name.endsWith("Service") || name.endsWith("Mapper")) set.add(name);
            }
        }
        return set;
    }

    private static Class<?> findServiceInterface(Class<?> controllerCls, String serviceName) {
        for (Field f : controllerCls.getDeclaredFields()) {
            if (f.getType().getSimpleName().equals(serviceName)) {
                return f.getType();
            }
        }
        return null;
    }

    // ===================== 【核心】同时获取 引入的 Service + Mapper =====================
    private static Set<String> getInsideServiceAndMapper(Class<?> serviceInterface) {
        Set<String> result = new LinkedHashSet<>();
        if (serviceInterface == null) return result;

        try {
            ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
            scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
            Set<BeanDefinition> beans = scanner.findCandidateComponents(BASE_PACKAGE);

            for (BeanDefinition bd : beans) {
                Class<?> implClass = Class.forName(bd.getBeanClassName());
                if (serviceInterface.isAssignableFrom(implClass)) {
                    for (Field f : implClass.getDeclaredFields()) {
                        if (f.isAnnotationPresent(javax.annotation.Resource.class) || f.isAnnotationPresent(Autowired.class)) {
                            String name = f.getType().getSimpleName();

                            // 只保留 Service 和 Mapper
                            boolean isService = name.endsWith("Service") || name.endsWith("ServiceImpl");
                            boolean isMapper = name.endsWith("Mapper");

                            if (isService || isMapper) {
                                result.add(name);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private static String getTableNames(Set<String> entities) {
        List<String> list = new ArrayList<>();
        for (String e : entities) {
            String t = getTableNameByEntity(e);
            if (t != null) list.add(t);
        }
        return list.isEmpty() ? "无" : String.join("、", list);
    }

    private static String getTableNameByEntity(String entity) {
        if (entity == null) return null;
        Class<?> c = ENTITY_MAP.get(entity);
        if (c == null) return null;
        TableName tn = c.getAnnotation(TableName.class);
        return tn == null ? entity : tn.value();
    }

    private static void addEmpty(List<Detail7ColumnExcel> list, String m, String b, String c, String f) {
        Detail7ColumnExcel row = new Detail7ColumnExcel();
        row.setModuleName(m);
        row.setControllerBasePath(b);
        row.setControllerName(c);
        row.setControllerFullClassName(f);
        row.setServiceName("无");
        row.setNestedServiceName("无");
        row.setEntityName("");
        row.setTableName("");
        list.add(row);
    }

    private static Set<Class<?>> scanAllControllers() {
        Set<Class<?>> set = new HashSet<>();
        ClassPathScanningCandidateComponentProvider scan = new ClassPathScanningCandidateComponentProvider(false);
        scan.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
        scan.addIncludeFilter(new AnnotationTypeFilter(Controller.class));
        for (BeanDefinition bd : scan.findCandidateComponents(BASE_PACKAGE)) {
            try {
                set.add(Class.forName(bd.getBeanClassName()));
            } catch (Exception e) {}
        }
        return set;
    }

    /*
    private static Set<Class<?>> scanAllControllers() {
        Set<Class<?>> set = new HashSet<>();
        try {
            // 【只加载 UserInfoController,其他全部不扫】
            Class<?> targetController = Class.forName("com.cnpc.riped.itms.controller.sysmanage.UserInfoController");
            set.add(targetController);
        } catch (Exception e) {}
        return set;
    }*/

    private static void scanAllEntities() {
        ClassPathScanningCandidateComponentProvider scan = new ClassPathScanningCandidateComponentProvider(false);
        scan.addIncludeFilter(new AnnotationTypeFilter(TableName.class));
        for (BeanDefinition bd : scan.findCandidateComponents(BASE_PACKAGE)) {
            try {
                Class<?> c = Class.forName(bd.getBeanClassName());
                ENTITY_MAP.put(c.getSimpleName(), c);
                ENTITY_SIMPLE_SET.add(c.getSimpleName());
            } catch (Exception e) {}
        }
    }

    private static String getTagModuleName(Class<?> c) {
        return c.isAnnotationPresent(Tag.class) ? c.getAnnotation(Tag.class).name() : "无模块";
    }

    private static String getClassRequestMapping(Class<?> c) {
        if (c.isAnnotationPresent(RequestMapping.class)) {
            String[] v = c.getAnnotation(RequestMapping.class).value();
            return v != null && v.length > 0 ? v[0] : "无";
        }
        return "无";
    }

    private static Class<?> getClassByName(String className) {
        try {
            List<Class<?>> allClasses = new ArrayList<>();

            // 1. 扫描所有 Service(正常)
            ClassPathScanningCandidateComponentProvider scanService = new ClassPathScanningCandidateComponentProvider(true);
            scanService.addIncludeFilter(new AnnotationTypeFilter(Service.class));
            for (BeanDefinition bd : scanService.findCandidateComponents(BASE_PACKAGE)) {
                allClasses.add(Class.forName(bd.getBeanClassName()));
            }

            // 2. 【多模块终极版】扫描所有 Mapper(跨模块生效)
            try {
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                String path = "classpath*:com/cnpc/riped/itms/**/*.class";
                Resource[] resources = resolver.getResources(path);
                MetadataReaderFactory factory = new CachingMetadataReaderFactory();

                for (Resource resource : resources) {
                    if (!resource.isReadable()) continue;
                    MetadataReader mr = factory.getMetadataReader(resource);
                    String clsName = mr.getClassMetadata().getClassName();

                    if (clsName.endsWith("Mapper")) {
                        allClasses.add(Class.forName(clsName));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 3. 匹配查找
            for (Class<?> c : allClasses) {
                if (c.getSimpleName().equals(className)) {
                    return c;
                }
                for (Class<?> itf : c.getInterfaces()) {
                    if (itf.getSimpleName().equals(className)) {
                        return itf;
                    }
                }
            }
        } catch (Exception e) {}
        return null;
    }

    // 【新增】统一获取实体:Service / Mapper 都支持
    private static String getEntityCommon(Class<?> clazz) {
        if (clazz == null) return null;

        // 解析 IService
        try {
            for (Type type : clazz.getGenericInterfaces()) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    if (pt.getRawType().getTypeName().contains("IService")) {
                        Type arg = pt.getActualTypeArguments()[0];
                        if (arg instanceof Class) {
                            return ((Class<?>) arg).getSimpleName();
                        }
                    }
                }
            }
        } catch (Exception ignored) {}

        // 解析 ServiceImpl
        try {
            Type superType = clazz.getGenericSuperclass();
            if (superType instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) superType;
                if (pt.getActualTypeArguments().length >= 2) {
                    return ((Class<?>) pt.getActualTypeArguments()[1]).getSimpleName();
                }
            }
        } catch (Exception ignored) {}

        // ==========================================
        // 【终极支持】直接解析所有 Mapper 泛型:
        // MPJBaseMapper<T>   BaseMapper<T>  全部支持
        // ==========================================
        try {
            Type[] genericInterfaces = clazz.getGenericInterfaces();
            for (Type type : genericInterfaces) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    Class<?> rawType = (Class<?>) pt.getRawType();

                    // 只要是 MyBatis 的 Mapper 接口,直接取第一个泛型
                    if (BaseMapper.class.isAssignableFrom(rawType) ||
                            rawType.getName().contains("MPJBaseMapper") ||
                            rawType.getName().endsWith("Mapper")) {

                        Type arg = pt.getActualTypeArguments()[0];
                        if (arg instanceof Class) {
                            return ((Class<?>) arg).getSimpleName();
                        }
                    }
                }
            }
        } catch (Exception ignored) {}



        return null;
    }

}

 

----------------------------------------------------------------3优化版------------------------------------------------------------------------------------

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
//汇总版:http://127.0.0.1:7011/admin/stats/export-final-7column
//明细版:http://127.0.0.1:7011/admin/stats/export-detail-7column

@Data
public class Detail7ColumnExcel {

    @ExcelProperty(value = "接口模块名称", index = 0)
    private String moduleName;

    @ExcelProperty(value = "Controller接口前缀", index = 1)
    private String controllerBasePath;

    @ExcelProperty(value = "Controller名称", index = 2)
    private String controllerName;

    @ExcelProperty(value = "Controller全类名", index = 3)
    private String controllerFullClassName;

    @ExcelProperty(value = "Service名称", index = 4)
    private String serviceName;

    @ExcelProperty(value = "引入Service名称", index = 5)
    private String nestedServiceName;

    @ExcelProperty(value = "关联实体类", index = 6)
    private String entityName;

    @ExcelProperty(value = "对应数据库表", index = 7)
    private String tableName;
}


import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class Final7ColumnExcel {

    @ExcelProperty(value = "接口模块名称", index = 0)
    private String moduleName;

    @ExcelProperty(value = "Controller接口前缀", index = 1)
    private String controllerBasePath;

    @ExcelProperty(value = "Controller名称", index = 2)
    private String controllerName;

    @ExcelProperty(value = "Controller全类名", index = 3)
    private String controllerFullClassName;

    @ExcelProperty(value = "Service名称", index = 4)
    private String serviceList;

    @ExcelProperty(value = "引入Service名称", index = 5)
    private String nestedServiceList;

    @ExcelProperty(value = "关联实体类", index = 6)
    private String entityList;

    @ExcelProperty(value = "对应数据库表", index = 7)
    private String tableList;
}

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/admin/stats")
public class Final7ColumnExportController {

    /**
     * 导出7列完整架构表
     */
    @GetMapping("/export-final-7column")
    public void exportFinal7Column(HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("微服务7列架构统计表.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        List<Final7ColumnExcel> dataList = Final7ColumnScanner.scan();

        EasyExcel.write(response.getOutputStream(), Final7ColumnExcel.class)
                .sheet("导出服务数据汇总")
                .doWrite(dataList);
    }

    /**
     * 明细版导出:一行一个 Service + 实体 + 表 完整组合
     */
    /*@GetMapping("/export-detail-7column")
    public void exportDetail7Column(HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("微服务7列架构明细表.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        List<Detail7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();

        EasyExcel.write(response.getOutputStream(), Detail7ColumnExcel.class)
                .sheet("7列架构明细")
                .doWrite(dataList);
    }*/

    @GetMapping("/export-detail-7column")
    public void exportDetail7Column(HttpServletResponse response) {
        try {
            // ========= 强制禁用缓存,防止断开连接 =========
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");

            String fileName = URLEncoder.encode("七列关系导出", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ExcelTypeEnum.XLSX.getValue());

            // ========= 获取数据(你现有的方法) =========
            //List<Final7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();
            List<Detail7ColumnExcel> dataList = Final7ColumnScanner.scanDetail();

            // ========= 写入 Excel(不关闭流,交给Tomcat) =========
            EasyExcel.write(response.getOutputStream(), Final7ColumnExcel.class)
                    .excelType(ExcelTypeEnum.XLSX)
                    .autoCloseStream(false) // ✅ 关键:禁止自动关闭流
                    .sheet("导出服务数据明细")
                    .doWrite(dataList);

        } catch (Exception e) {
            // 忽略客户端断开异常,防止报错
            if (!e.getMessage().contains("Connection reset by peer") &&
                    !e.getMessage().contains("已建立的连接")) {
                e.printStackTrace();
            }
        }
    }
}



import org.springframework.core.annotation.AnnotationUtils;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

public final class Final7ColumnScanner {

    private static final String BASE_PACKAGE = "xxx";
    private static final Map<String, Class<?>> ENTITY_MAP = new HashMap<>();
    private static final Set<String> ENTITY_SIMPLE_SET = new HashSet<>();
    private static final Set<Class<?>> CONTROLLER_SET = new HashSet<>();
    private static final Map<String, Class<?>> SERVICE_CLASS_CACHE = new HashMap<>();
    private static final Map<String, Class<?>> MAPPER_CLASS_CACHE = new HashMap<>();
    private static final Map<String, Class<?>> SIMPLE_NAME_TO_CLASS = new HashMap<>();

    static {
        // 全局只扫描一次!!!
        initAllClass();
    }

    private static void initAllClass() {
        scanAllEntities();
        scanAllControllers();
        scanAllServices();
        scanAllMappers();
        buildSimpleNameCache();
    }

    // ========================= 【全局缓存】 =========================
    private static void scanAllServices() {
        ClassPathScanningCandidateComponentProvider scan = new ClassPathScanningCandidateComponentProvider(true);
        scan.addIncludeFilter(new AnnotationTypeFilter(Service.class));
        for (BeanDefinition bd : scan.findCandidateComponents(BASE_PACKAGE)) {
            try {
                Class<?> cls = Class.forName(bd.getBeanClassName());
                SERVICE_CLASS_CACHE.put(cls.getName(), cls);
                for (Class<?> itf : cls.getInterfaces()) {
                    SERVICE_CLASS_CACHE.put(itf.getName(), itf);
                }
            } catch (Exception ignored) {}
        }
    }

    private static void scanAllMappers() {
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            String path = "classpath*:com/cnpc/riped/itms/**/*.class";
            Resource[] resources = resolver.getResources(path);
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();

            for (Resource resource : resources) {
                if (!resource.isReadable()) continue;
                MetadataReader mr = factory.getMetadataReader(resource);
                String clsName = mr.getClassMetadata().getClassName();
                if (clsName.endsWith("Mapper")) {
                    try {
                        Class<?> cls = Class.forName(clsName);
                        MAPPER_CLASS_CACHE.put(clsName, cls);
                    } catch (Exception ignored) {}
                }
            }
        } catch (Exception ignored) {}
    }

    private static void buildSimpleNameCache() {
        for (Class<?> cls : SERVICE_CLASS_CACHE.values()) {
            SIMPLE_NAME_TO_CLASS.put(cls.getSimpleName(), cls);
        }
        for (Class<?> cls : MAPPER_CLASS_CACHE.values()) {
            SIMPLE_NAME_TO_CLASS.put(cls.getSimpleName(), cls);
        }
        for (Class<?> cls : ENTITY_MAP.values()) {
            SIMPLE_NAME_TO_CLASS.put(cls.getSimpleName(), cls);
        }
    }

    // ========================= 工具方法(O(1)) =========================
    private static Class<?> getClassByName(String simpleName) {
        return SIMPLE_NAME_TO_CLASS.get(simpleName);
    }

    // ========================= 原逻辑(不变,但速度爆炸) =========================
    public static List<Final7ColumnExcel> scan() {
        List<Final7ColumnExcel> resultList = new ArrayList<>();

        for (Class<?> controllerCls : CONTROLLER_SET) {
            String moduleName = getTagModuleName(controllerCls);
            String basePath = getClassRequestMapping(controllerCls);
            String controllerName = controllerCls.getSimpleName();
            String fullClassName = controllerCls.getName();

            Set<String> mainServices = getDirectServiceList(controllerCls);
            Set<String> allNested = new LinkedHashSet<>();
            Set<String> allEntities = new LinkedHashSet<>();

            for (String s : mainServices) {
                Class<?> itf = getClassByName(s);
                if (itf == null) continue;

                Set<String> nested = getInsideServiceAndMapper(itf);
                allNested.addAll(nested);

                String mainEnt = getEntityCommon(itf);
                if (mainEnt == null) {
                    mainEnt = s.replace("Service", "").replace("Impl", "");
                    if (mainEnt.startsWith("I")) mainEnt = mainEnt.substring(1);
                }
                if (ENTITY_SIMPLE_SET.contains(mainEnt)) {
                    allEntities.add(mainEnt);
                }

                for (String nestedName : nested) {
                    Class<?> nestedClazz = getClassByName(nestedName);
                    if (nestedClazz == null) continue;
                    String nestedEnt = getEntityCommon(nestedClazz);
                    if (nestedEnt != null && ENTITY_SIMPLE_SET.contains(nestedEnt)) {
                        allEntities.add(nestedEnt);
                    }
                }
            }

            Final7ColumnExcel row = new Final7ColumnExcel();
            row.setModuleName(moduleName);
            row.setControllerBasePath(basePath);
            row.setControllerName(controllerName);
            row.setControllerFullClassName(fullClassName);
            row.setServiceList(String.join("、", mainServices));
            row.setNestedServiceList(String.join("、", allNested));
            row.setEntityList(String.join("、", allEntities));
            row.setTableList(getTableNames(allEntities));
            resultList.add(row);
        }
        return resultList;
    }

    public static List<Detail7ColumnExcel> scanDetail() {
        List<Detail7ColumnExcel> resultList = new ArrayList<>();

        for (Class<?> controllerCls : CONTROLLER_SET) {
            String moduleName = getTagModuleName(controllerCls);
            String basePath = getClassRequestMapping(controllerCls);
            String controllerName = controllerCls.getSimpleName();
            String fullClassName = controllerCls.getName();

            Set<String> mainServices = getDirectServiceList(controllerCls);
            if (mainServices.isEmpty()) {
                addEmpty(resultList, moduleName, basePath, controllerName, fullClassName);
                continue;
            }

            for (String mainService : mainServices) {
                Class<?> mainItf = getClassByName(mainService);
                if (mainItf == null) continue;

                Set<String> insideList = getInsideServiceAndMapper(mainItf);
                String mainEntity = getEntityCommon(mainItf);
                String mainTable = getTableNameByEntity(mainEntity);

                Detail7ColumnExcel mainRow = new Detail7ColumnExcel();
                mainRow.setModuleName(moduleName);
                mainRow.setControllerBasePath(basePath);
                mainRow.setControllerName(controllerName);
                mainRow.setControllerFullClassName(fullClassName);
                mainRow.setServiceName(mainService);
                mainRow.setNestedServiceName(mainService);
                mainRow.setEntityName(mainEntity == null ? "" : mainEntity);
                mainRow.setTableName(mainTable == null ? "" : mainTable);
                resultList.add(mainRow);

                if (insideList.isEmpty()) {
                    Detail7ColumnExcel row = new Detail7ColumnExcel();
                    row.setModuleName(moduleName);
                    row.setControllerBasePath(basePath);
                    row.setControllerName(controllerName);
                    row.setControllerFullClassName(fullClassName);
                    row.setServiceName(mainService);
                    row.setNestedServiceName("无");
                    row.setEntityName(mainEntity == null ? "" : mainEntity);
                    row.setTableName(mainTable == null ? "" : mainTable);
                    resultList.add(row);
                } else {
                    for (String nested : insideList) {
                        Class<?> nestedClazz = getClassByName(nested);
                        if (nestedClazz == null) continue;

                        String entity = getEntityCommon(nestedClazz);
                        String table = getTableNameByEntity(entity);

                        Detail7ColumnExcel row = new Detail7ColumnExcel();
                        row.setModuleName(moduleName);
                        row.setControllerBasePath(basePath);
                        row.setControllerName(controllerName);
                        row.setControllerFullClassName(fullClassName);
                        row.setServiceName(mainService);
                        row.setNestedServiceName(nested);
                        row.setEntityName(entity == null ? "" : entity);
                        row.setTableName(table == null ? "" : table);
                        resultList.add(row);
                    }
                }
            }
        }
        return resultList;
    }

    // ========================= 以下方法基本不变 =========================
    private static Set<String> getDirectServiceList(Class<?> controllerCls) {
        Set<String> set = new LinkedHashSet<>();
        for (Field f : controllerCls.getDeclaredFields()) {
            if (f.isAnnotationPresent(javax.annotation.Resource.class) || f.isAnnotationPresent(Autowired.class)) {
                String name = f.getType().getSimpleName();
                if (name.endsWith("Service") || name.endsWith("Mapper")) {
                    set.add(name);
                }
            }
        }
        return set;
    }

    /*private static Set<String> getInsideServiceAndMapper(Class<?> serviceInterface) {
        Set<String> result = new LinkedHashSet<>();
        if (serviceInterface == null) return result;

        try {
            for (Class<?> implClass : SERVICE_CLASS_CACHE.values()) {
                if (serviceInterface.isAssignableFrom(implClass)) {
                    for (Field f : implClass.getDeclaredFields()) {
                        if (f.isAnnotationPresent(javax.annotation.Resource.class) || f.isAnnotationPresent(Autowired.class)) {
                            String name = f.getType().getSimpleName();
                            boolean isService = name.endsWith("Service") || name.endsWith("ServiceImpl");
                            boolean isMapper = name.endsWith("Mapper");
                            if (isService || isMapper) {
                                result.add(name);
                            }
                        }
                    }
                    break;
                }
            }
        } catch (Exception ignored) {}
        return result;
    }*/

    private static Set<String> getInsideServiceAndMapper(Class<?> serviceInterface) {
        Set<String> result = new LinkedHashSet<>();
        if (serviceInterface == null) return result;

        try {
            // 拿到接口简单名称:AgileRequirementSubmissionService
            String interfaceName = serviceInterface.getSimpleName();

            for (Class<?> implClass : SERVICE_CLASS_CACHE.values()) {
                String implClassName = implClass.getSimpleName();

                // ==========================================
                // 核心兼容逻辑:只要是 接口名 + Impl 就认定是实现类
                // 无视包名、无视是否 implements、无视拼写错误
                // ==========================================
                if (implClassName.equals(interfaceName + "Impl")) {

                    // 开始扫描字段
                    for (Field f : implClass.getDeclaredFields()) {
                        // 判断是否注入注解
                        if (f.isAnnotationPresent(javax.annotation.Resource.class)
                                || f.isAnnotationPresent(org.springframework.beans.factory.annotation.Autowired.class)) {

                            String name = f.getType().getSimpleName();
                            boolean isService = name.endsWith("Service") || name.endsWith("ServiceImpl");
                            boolean isMapper = name.endsWith("Mapper");

                            if (isService || isMapper) {
                                result.add(name);
                            }
                        }
                    }
                    break;
                }
            }
        } catch (Exception ignored) {
            // 不抛异常
        }
        return result;
    }

    private static String getTableNames(Set<String> entities) {
        List<String> list = new ArrayList<>();
        for (String e : entities) {
            String t = getTableNameByEntity(e);
            if (t != null) list.add(t);
        }
        return list.isEmpty() ? "无" : String.join("、", list);
    }

    private static String getTableNameByEntity(String entity) {
        if (entity == null) return null;
        Class<?> c = ENTITY_MAP.get(entity);
        if (c == null) return null;
        TableName tn = AnnotationUtils.findAnnotation(c, TableName.class);
        return tn == null ? entity : tn.value();
    }

    private static void addEmpty(List<Detail7ColumnExcel> list, String m, String b, String c, String f) {
        Detail7ColumnExcel row = new Detail7ColumnExcel();
        row.setModuleName(m);
        row.setControllerBasePath(b);
        row.setControllerName(c);
        row.setControllerFullClassName(f);
        row.setServiceName("无");
        row.setNestedServiceName("无");
        row.setEntityName("");
        row.setTableName("");
        list.add(row);
    }

    private static void scanAllControllers() {
        ClassPathScanningCandidateComponentProvider scan = new ClassPathScanningCandidateComponentProvider(false);
        scan.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
        scan.addIncludeFilter(new AnnotationTypeFilter(Controller.class));
        for (BeanDefinition bd : scan.findCandidateComponents(BASE_PACKAGE)) {
            try {
                CONTROLLER_SET.add(Class.forName(bd.getBeanClassName()));
                //CONTROLLER_SET.add(Class.forName("com.cnpc.riped.itms.controller.requirementsubmission.AgileRequirementSubmissionController"));
                //CONTROLLER_SET.add(Class.forName("com.cnpc.riped.itms.controller.maintenanceproject.TMaintenanceprojectBasicinformationController"));
            } catch (Exception ignored) {}
        }
    }

    private static void scanAllEntities() {
        ClassPathScanningCandidateComponentProvider scan = new ClassPathScanningCandidateComponentProvider(false);
        scan.addIncludeFilter(new AnnotationTypeFilter(TableName.class));
        for (BeanDefinition bd : scan.findCandidateComponents(BASE_PACKAGE)) {
            try {
                Class<?> c = Class.forName(bd.getBeanClassName());
                ENTITY_MAP.put(c.getSimpleName(), c);
                ENTITY_SIMPLE_SET.add(c.getSimpleName());
            } catch (Exception ignored) {}
        }
    }

    private static String getTagModuleName(Class<?> c) {
        Tag tag = AnnotationUtils.findAnnotation(c, Tag.class);
        return tag != null ? tag.name() : "无模块";
    }

    private static String getClassRequestMapping(Class<?> c) {
        RequestMapping rm = AnnotationUtils.findAnnotation(c, RequestMapping.class);
        if (rm == null) return "无";
        String[] v = rm.value();
        return (v != null && v.length > 0) ? v[0] : "无";
    }

    private static String getEntityCommon(Class<?> clazz) {
        if (clazz == null) return null;

        try {
            for (Type type : clazz.getGenericInterfaces()) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    if (pt.getRawType().getTypeName().contains("IService")) {
                        return ((Class<?>) pt.getActualTypeArguments()[0]).getSimpleName();
                    }
                }
            }
        } catch (Exception ignored) {}

        try {
            Type superType = clazz.getGenericSuperclass();
            if (superType instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) superType;
                if (pt.getActualTypeArguments().length >= 2) {
                    return ((Class<?>) pt.getActualTypeArguments()[1]).getSimpleName();
                }
            }
        } catch (Exception ignored) {}

        try {
            for (Type type : clazz.getGenericInterfaces()) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) type;
                    Class<?> rawType = (Class<?>) pt.getRawType();
                    if (BaseMapper.class.isAssignableFrom(rawType) || rawType.getName().endsWith("Mapper")) {
                        return ((Class<?>) pt.getActualTypeArguments()[0]).getSimpleName();
                    }
                }
            }
        } catch (Exception ignored) {}

        return null;
    }
}

  

 

posted @ 2026-05-12 11:08  hanease  阅读(12)  评论(0)    收藏  举报