模拟IOC简易扫描器
Posted africanhusky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟IOC简易扫描器相关的知识,希望对你有一定的参考价值。
浅析xml文件中的IOC自动扫描器原理
<context:component-scan base-package="cn.scanner"/>
第一步:获取自动扫描的package的范围
base-package="cn.scanner"
第二步:获取指定范围内的包中的所有class文件
D:/java_project/week14_03_spring01/target/classes/cn/scanner
D:/java_project/week14_03_spring01/target/classes/cn/scanner/controller
.....
第三步:判断class文件中是否标注了指定的注解
如果标注了注解,则实例化类对象
附本地的文件夹结构
1 public class AutoScanner { 2 private static List<String> clazz = new ArrayList<>(); 3 private static Map<String,Object> map = new HashMap<>(); 4 public static void main(String[] args){ 5 //设置扫描的范围为cn.scanner包下的所有内容 6 String sourcePackage = "cn.scanner"; 7 //调用方法 获取该范围下所有类的全限定名 8 getAllClass(sourcePackage); 9 //实例化对象 10 instanceBeans(); 11 } 12 13 /** 14 * 实例化已存在,并且标识了注释的类 15 */ 16 public static void instanceBeans(){ 17 //判断集合是否无内容 18 if(clazz.size()>0){ 19 //遍历全限定名集合 20 for(String str : clazz){ 21 try { 22 //尝试从被扫描到的类中获取注解对象 23 TestAnnotation testAnnotation = Class.forName(str).getAnnotation(TestAnnotation.class); 24 //如果当前类未标识该注释 则注释对象为空 25 if(null != testAnnotation){ 26 //通过全限定名实例化类对象 27 Object obj = Class.forName(str).newInstance(); 28 //截取全限定名 只保留最后一个‘.‘后的内容 29 str = str.substring(str.lastIndexOf(".")+1); 30 //遵循spring框架的id命名规则 首字母小写 后面的字符保持不变 31 String key = str.toLowerCase().charAt(0)+str.substring(1); 32 map.put(key,obj); 33 } 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 } 38 } 39 } 40 41 /** 42 * 获取类的全限定名集合 43 * @param sourcePackage 44 */ 45 private static void getAllClass(String sourcePackage) { 46 System.out.println("当前在:"+sourcePackage+"包中"); 47 //由于在方法中无法调用this,所以只能调用当前线程的类加载器来获取url 48 URL url = Thread.currentThread().getContextClassLoader().getResource(replacePath(sourcePackage)); 49 String basePath = url.getPath(); 50 System.out.println("当前包的完整路径:"+basePath); 51 //用于储存当前路径下的所有文件的路径 52 String[] subPaths = new File(basePath).list(); 53 for(String sub : subPaths){ 54 String subFilePath = basePath+"/"+sub; 55 File subFile = new File(subFilePath); 56 System.out.println("扫描到文件:"+subFile.getName()); 57 //判断该文件是否为文件夹 58 if(subFile.isDirectory()){ 59 System.out.println(" 该文件是文件夹"); 60 System.out.println(" 进入"+subFile.getName()+"包中"); 61 getAllClass(sourcePackage+"."+subFile.getName()); 62 }else{ 63 System.out.println(" 该文件不是文件夹"); 64 String fullName = sourcePackage+"."+subFile.getName(); 65 fullName = fullName.replace(".class",""); 66 //如果该文件不是文件夹,则将它的全限定名存入集合备用 67 clazz.add(fullName); 68 System.out.println(" 将文件的全限定名"+fullName+"存入集合中"); 69 } 70 } 71 } 72 73 /** 74 * 将字符串中的‘.‘转换为‘/‘ 75 * @param str 76 * @return 77 */ 78 private static String replacePath(String str){ 79 return str.replaceAll("\\.","\\/"); 80 } 81 }
当前在:cn.scanner包中 当前包的完整路径:/D:/java_project/week14_03_spring01/target/classes/cn/scanner 扫描到文件:AutoScanner.class 该文件不是文件夹 将文件的全限定名cn.scanner.AutoScanner存入集合中 扫描到文件:controller 该文件是文件夹 进入controller包中 当前在:cn.scanner.controller包中 当前包的完整路径:/D:/java_project/week14_03_spring01/target/classes/cn/scanner/controller 扫描到文件:TestController.class 该文件不是文件夹 将文件的全限定名cn.scanner.controller.TestController存入集合中 扫描到文件:dao 该文件是文件夹 进入dao包中 当前在:cn.scanner.dao包中 当前包的完整路径:/D:/java_project/week14_03_spring01/target/classes/cn/scanner/dao 扫描到文件:TestDao.class 该文件不是文件夹 将文件的全限定名cn.scanner.dao.TestDao存入集合中 扫描到文件:service 该文件是文件夹 进入service包中 当前在:cn.scanner.service包中 当前包的完整路径:/D:/java_project/week14_03_spring01/target/classes/cn/scanner/service 扫描到文件:TestService.class 该文件不是文件夹 将文件的全限定名cn.scanner.service.TestService存入集合中 扫描到文件:TestAnnotation.class 该文件不是文件夹 将文件的全限定名cn.scanner.TestAnnotation存入集合中
如有写错的地方,希望有研究的朋友指出,谢谢!
以上是关于模拟IOC简易扫描器的主要内容,如果未能解决你的问题,请参考以下文章
手写实现自定义简易版Spring (实现IoC 和 AOP)