创建一个自定义的spring容器(XykApplicationContext),在里面接收外面传进来的配置类,创建一个有参构造方法,创建一个存储bean的Map单例池。
1、调用XykApplicationContext的有参构造方法,判断传进来的这个类是否包含@ComponentScan注解。
2、根据传进来的@ComponentScan注解获取value里面的信息,如果没有配置value信息为空,就将当前地址进行剪切,拿到当前包的路径
3、获取value里面的扫描路径
4、获取编译后.class文件里的service目录下的所有文件,将com.xyk.service替换为com/xyk/service
5、获取XykApplicationContext对应的应用程序类加载器(AppClassLoader)
6、获取当前相对路径下的文件,相对的是应用程序类加载器对应的target/classes,再根据path找到当前路径下的文件
7、获取当前路径下的目录
8、遍历当前路径下的一个个文件,再判断是不是文件
1)遍历路径下的文件
2)通过类加载器将.class文件加载成一个class对象,再判断里面是否包含Component注解
3)先将类路径截取下来,再将/替换成.
9、将bean的名字存入Map集合,如果有注解,没有配置名字,将类名截取出来首字母小写当做bean的名字,如果加入了@Scope注解,判断@Scope注解里面是否是原型bean还是单例bean,是单例bean添加到单例池中。
private void scan(Class configClass) { if(configClass.isAnnotationPresent(ComponentScan.class)){ ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class); String path = componentScanAnnotation.value(); path = path.replace(".","/"); ClassLoader classLoader = XykApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(path);\service File file = new File(resource.getFile()); if(file.isDirectory()){ for (File f : file.listFiles()) { String absolutePath = f.getAbsolutePath(); absolutePath = absolutePath.substring(absolutePath.indexOf("com"),absolutePath.indexOf(".class")); absolutePath = absolutePath.replace("\\","."); try { Class<?> clazz = classLoader.loadClass(absolutePath); if (clazz.isAnnotationPresent(Component.class)) { Component componentAnnotation = clazz.getAnnotation(Component.class); String beanName = componentAnnotation.value(); if(beanName.isEmpty() || beanName == ""){ String[] split = clazz.toString().split("\\."); beanName = split[split.length - 1].replace(split[split.length - 1].substring(0, 1), split[split.length - 1].substring(0, 1).toLowerCase()); } BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setType(clazz); if (clazz.isAnnotationPresent(Scope.class)) { Scope scopeAnnotation = clazz.getAnnotation(Scope.class); String value = scopeAnnotation.value(); beanDefinition.setScope(value); }else{ beanDefinition.setScope("singleton"); } beanDefinitionMap.put(beanName,beanDefinition); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } }