if (configClass.isAnnotationPresent(ComponentScan.class)) { ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class); // 1.1 扫描路径:只是个包名,扫描的是java的class文件,而并非源文件,com.lyd.service String path = componentScanAnnotation.value(); // 1.2 将路径文件替换成/的形式 path = path.replace(".","/"); // 1.3 通过类加载器获取资源路径 ClassLoader classLoader = LydApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(path); // 1.4 转成文件形式,主要是为了获取他的绝对地址 File file = new File(resource.getFile()); System.out.println(file);}通过类加载器得到的资源有个获取File的方法,然后我们通过File file = new File(resource.getFile());将资源转成File类型,因为他可以表示一个地址或者是具体文件 。扫描就是扫描文件路径,也就是文件夹 。我们可以打印看一下这个地址:

文章插图
判断是否为文件夹,如果是,那就获取里面的所有文件,在通过遍历这些文件,获取绝对路径 。
if (file.isDirectory()) { // 如果是文件夹 File[] files = file.listFiles(); for (File f : files) { String absolutePath = f.getAbsolutePath(); // 获取绝对路径 System.out.println("绝对路径:" + absolutePath); }}我们可以打印出来看一下:
因为我们要的是编译的.class文件,因此需要在遍历文件的时候进行判断文件是否为.class文件 。为了拿到这个类,需要通过全限定名使用类加载器获取类,也就是利用反射机制 。我们都知道,spring是通过Component注解来将bean注入spring的,因此最后就是通过判断是否有这个注解来得到一个bean 。
for (File f : files) { String absolutePath = f.getAbsolutePath(); // 获取绝对路径 System.out.println("绝对路径:" + absolutePath); // 1.5 对编译文件进行处理 if (absolutePath.endsWith(".class")) { // 判断是否为编译文件/** * 需要拿到的是编译文件,通过类加载器去获取 * 需要将com\lyd\service\UserService转成com.lyd.service.UserService */String className = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));className = className.replace("\\", ".");System.out.println("类名:" + className);try {// 1.6 通过全限定名使用类加载器获取类 (利用反射机制)Class<?> clazz = classLoader.loadClass(className);// 1.7 在通过这个clazz(类)来判断是否有component注解,有则是beanif (clazz.isAnnotationPresent(Component.class)) {// 到这里就是一个bean}} catch (Exception e) {e.printStackTrace();} }}最后我们需要的地址就是如下:
Spring生成BeanDefinition在我们Spring容器启动或者是扫描的时候,并不建议直接实例化bean对象,因为bean是区分单例和多例的,多例bean我们是需要用到的时候再去创建 。这个时候就需要生成BeanDefinition,即bean的定义,这个类存储了类和作用域(单例还是多例) 。
经验总结扩展阅读
- 冰的熔点是多少
- 【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
- 基础版 【网络】内网穿透方案&FRP内网穿透实战
- 金线莲的吃法
- 2023年9月6日是疏通管道吉日吗 2023年9月6日适合疏通管道吗
- 半亩是多少
- 银耳可以泡一晚上再煮吗
- 熊猫便便有什么用
- 清除青苔最有效的方法
- 油是导体还是绝缘体