1 概要

1.1 目标:spring 的核心框架,就是依赖注入,后面的一切框架都是基于这样基础丰富的整个spring生态圈。为了对整个生态圈,有一个形象的认识,我准备做一个简单的框架。今天先模拟一个包的扫描,然后在这个基础上,再加上远程调用和负载均衡基本上就把微服务的核心功能模拟完了。

1.2 要点

  1. 获取包名String basePackageName = this.getClass().getPackage().getName();
  2. 获取包路径 
    lassLoader loader = ClassLoader.getSystemClassLoader();
    Enumeration<URL> enums = loader.getResources(path);
  3. 获取包路线下的类文件
    File dir = new File(dirPath);
    if (dir.isDirectory()) {
        File[] var8 = dir.listFiles();
  4. 生成类
    classes.add(Class.forName(basePackageName + "." + className));
  5. 生成类对象
    Object mqConst = aClass.newInstance();

2 代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.example;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class Main {
    public Main() {
    }

    public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException {
        Main main = new Main();
        main.main();
        System.out.println("Hello world!");
    }

    private void main() throws IOException, InstantiationException, IllegalAccessException {
        String basePackageName = this.getClass().getPackage().getName();
        System.out.println(basePackageName);
        String path = basePackageName.replace(".", "\\");
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        Enumeration<URL> enums = loader.getResources(path);
        String dirPath = "";

        while(enums.hasMoreElements()) {
            URL url = (URL)enums.nextElement();
            if (url != null) {
                String protool = url.getProtocol();
                System.out.println("url.getProtocol:" + protool);
                if ("file".equals(protool)) {
                    dirPath = url.getPath();
                    dirPath = URLDecoder.decode(dirPath, "utf-8");
                    System.out.println(dirPath);
                }
            }
        }

        List<String> classNameList = new ArrayList();
        File dir = new File(dirPath);
        if (dir.isDirectory()) {
            File[] var8 = dir.listFiles();
            int var9 = var8.length;

            for(int var10 = 0; var10 < var9; ++var10) {
                File f = var8[var10];
                String fileName = f.getName();
                System.out.println(fileName);
                String[] split = fileName.split("\\.");
                if (split.length == 2 && split[1].equals("class")) {
                    fileName = fileName.substring(0, fileName.lastIndexOf("."));
                    System.out.println("类名:" + fileName);
                    classNameList.add(fileName);
                }
            }
        }

        System.out.println("\n 获取的类");
        List<Class<?>> classes = new ArrayList();
        Iterator var24 = classNameList.iterator();

        while(var24.hasNext()) {
            String className = (String)var24.next();

            try {
                System.out.println("Class.forName:" + basePackageName + "." + className);
                classes.add(Class.forName(basePackageName + "." + className));
            } catch (ClassNotFoundException var20) {
                var20.printStackTrace();
            }
        }

        System.out.println("\n 生成的类");
        Set<String> set = new HashSet();
        Iterator var27 = classes.iterator();

        while(var27.hasNext()) {
            Class<?> aClass = (Class)var27.next();
            System.out.println("生成的对象" + aClass.getName());
            Object mqConst = aClass.newInstance();
            Field[] fields = aClass.getFields();
            Field[] var14 = fields;
            int var15 = fields.length;

            for(int var16 = 0; var16 < var15; ++var16) {
                Field field = var14[var16];
                String fieldName = field.getName();
                String queueName = field.get(mqConst).toString();
                System.out.println("    可以注册的字段名称:" + fieldName + ",字段值:" + queueName);
                set.add(queueName);
            }
        }

    }
}

3 运行效果

C:\Users\ThinkPad\.jdks\openjdk-21.0.2\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2023.3.2\lib\idea_rt.jar=52732:D:\Program Files\JetBrains\IntelliJ IDEA 2023.3.2\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\Users\ThinkPad\IdeaProjects\untitled7\untitled5\target\classes org.example.Main
org.example
url.getProtocol:file
/C:/Users/ThinkPad/IdeaProjects/untitled7/untitled5/target/classes/org\example
Main.class
类名:Main
Test1.class
类名:Test1
Test2.class
类名:Test2

 获取的类
Class.forName:org.example.Main
Class.forName:org.example.Test1
Class.forName:org.example.Test2

 生成的类
生成的对象org.example.Main
生成的对象org.example.Test1
    可以注册的字段名称:a,字段值:1
    可以注册的字段名称:b,字段值:sss
生成的对象org.example.Test2
    可以注册的字段名称:c,字段值:7
    可以注册的字段名称:d,字段值:ddd
Hello world!

Process finished with exit code 0
01-30 04:34