手写Spring基础源码(1)

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。手写Spring基础源码(1),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

通过手写模拟Spring源码了解Spring底层源码启动原理与工作工程。第一部分为通过@ComponetScan扫描相应的包获取Bean实例。这里未设置@Scope,默认都是单例。


一、目录结构

手写Spring基础源码(1)

二、相关部分代码

1.Spring启动类

public class Test {
    public static void main(String args[]){
        try {
            ApplicationContext applicationContext=new ApplicationContext(AppConfig.class);
             Userservice bean = (Userservice)applicationContext.getBean("userservice");
             bean.test();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

2.AppConfig类和ComponentScan注解

@ComponentScan("com.example.service")
public class AppConfig {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {
    String value() default "";
}

3. BeanDefinition类

public class BeanDefinition {
    private  Class clazz;

    public BeanDefinition(Class clazz) {
        this.clazz = clazz;
    }

    public BeanDefinition() {
    }

    public Class getClazz() {
        return clazz;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }
}

4.ApplicationContext类

获取配置类的注解扫描路径,通过类加载器获取该路径下的资源,然后遍历资源下的各个文件,判断当前类是不是一个Bean实例,将BeanName和BeanDefinition对象存储到Map集合中。然后遍历该Map集合,添加到单例池中。

public ApplicationContext(Class configClass) throws ClassNotFoundException {
        this.configClass = configClass;
        ComponentScan annotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
        String value = annotation.value();
        System.out.println(value);
        value=value.replace('.','/');
//        类加载器应用
        ClassLoader classLoader=ApplicationContext.class.getClassLoader();
//        获取类加载器下当前目录下的资源
        URL resource = classLoader.getResource(value);
        File file=new File(resource.getFile());
        if(file.isDirectory()){
            File[] files=file.listFiles();
            for(File f:files){
//                获取当前资源下的class文件
                String absolutePath = f.getAbsolutePath();
                if(absolutePath.endsWith(".class")){
                    String className=absolutePath.substring(absolutePath.indexOf("com"),absolutePath.indexOf(".class"));
                    className=className.replace("\\",".");
                    Class<?> loadClass = classLoader.loadClass(className);
                    if(loadClass.isAnnotationPresent(Componet.class)){
                        Componet declaredAnnotation = loadClass.getDeclaredAnnotation(Componet.class);
                        String value1 = declaredAnnotation.value();
                        BeanDefinition beanDefinition=new BeanDefinition();
                        beanDefinition.setClazz(loadClass);
                        beanDefinitionHashMap.put(value1,beanDefinition);

                    }
                }
            }
        }
        for(String beanName:beanDefinitionHashMap.keySet()){
               BeanDefinition beanDefinition=beanDefinitionHashMap.get(beanName);
            Object bean = createBean(beanDefinition);
            hashMap.put(beanName,bean);
        }



    }

createBean方法

 public  Object createBean(BeanDefinition beanDefinition){
         Class clazz=beanDefinition.getClazz();
        try {
            Object o = clazz.getDeclaredConstructor().newInstance();
            return o;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;

    }

getBean方法

public Object getBean(String beanName){
        if(beanDefinitionHashMap.containsKey(beanName)){
            BeanDefinition beanDefinition = beanDefinitionHashMap.get(beanName);
            Object o = hashMap.get(beanName);
            return o;

        }
        else {
            throw new NullPointerException();
        }
    }

总结

通过简单手写Spring源码,有了更深的理解。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/197085.html

(2)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!