spring源码第一天---扫描

创建一个自定义的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();
                }
            }
        }
    }
}
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值