spring容器-简单落地

125 阅读2分钟

(参阅5.3spring源码简单实现)

许久未曾专注的写过文章。实在有些对不住,也想了很长时间了,于是就专门输出点东西吧。言归正传。此间代码查阅于【spring3.5.10】网上资料很多关于编译spring源码的,故此省略。

image.png 从spring-context的测试包下开始。 
AnnotationConfigApplicationContext 做了三件事, 
第一个扫描包

image.png 主要目的获取> BeanDefinition 
第二个刷新容器 
第三则是获取容器中的Bean 
故而,模拟实现也可以根据此来。 
开始项目,新建项目

image.png 无任何引用的jar包 
具体的结构如下

image.png

直接看结果,TeacherService,StudentService都注入并有值,就此简单实现完成。

image.png

主要代码块


public AnnotationApplicationContext(Class clazz) {

        scanner(clazz);

        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {

            String beanName = entry.getKey();

            BeanDefinition beanDefinition = entry.getValue();
           //单例
          if (ConfigurableBeanFactory.SCOPE_SINGLETON.equals(beanDefinition.getScope()){

              Object bean = createBean(beanName, beanDefinition);

              singletonObjects.put(beanName, bean);

          }

        }

 }



//主要扫描单例非懒加载的Bean,扫描包路径,添加到BeanDefinition中,相当于容器;后续或根据Definition生成对应类

private void scanner(Class clazz) {

        if (clazz.isAnnotationPresent(ComponentScan.class)) {

            ComponentScan componentScanAnnotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);

            String value = componentScanAnnotation.value();

            String replace = value.replace(".", "/");



        //加载class

        ClassLoader classLoader = AnnotationApplicationContext.class.getClassLoader();

        URL url = classLoader.getResource(replace);

        File mainFile = new File(url.getFile());

        if (mainFile.isAbsolute()) {

            for (File file : mainFile.listFiles()) {

                String absolutePath = file.getAbsolutePath();

                String s = absolutePath.substring(absolutePath.indexOf("cn"), absolutePath.indexOf(".class"))

                        .replace("\\", ".");

                try {

                    Class<?> aClass = classLoader.loadClass(s);

                    if (aClass.isAnnotationPresent(Component.class)) {

                        Component componentAnnotation = aClass.getAnnotation(Component.class);

                        String beanName = componentAnnotation.value();

                        if (Objects.equals("", beanName)) {

                            // 此处注意,如果类为ABTest 则生成的Bean为ABTtest

                            beanName = Introspector.decapitalize(aClass.getSimpleName());

                        }

                        BeanDefinition definition = new BeanDefinition();

                        definition.setBeanClass(aClass);

                        if (aClass.isAnnotationPresent(Scope.class)) {

                            Scope annotation = aClass.getAnnotation(Scope.class);

                            definition.setScope(annotation.value());

                        } else {

                            definition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON);

                        }

                        beanDefinitionMap.put(beanName, definition);

                    }

                } catch (ClassNotFoundException e) {

                    e.printStackTrace();

                }

            }

        }



    }

}



//扫描完成,根据BeanDefinition生成对象

private Object createBean(String beanName, BeanDefinition beanDefinition) {

    Class clazz = beanDefinition.getBeanClass();

    Object instance = null;

    try {

        instance = clazz.getConstructor().newInstance();

        for (Field field : clazz.getDeclaredFields()) {

            if (field.isAnnotationPresent(Autowired.class)) {

                field.setAccessible(true);

                field.set(instance, getBean(field.getName()));

            }

        }

        //后续还有初始化Aware操作;SmartInitializingSingleton单例非懒加载之后操作;BeanFactory初始化前,后操作;InitializingBean>afterPropertiesSet();PostConstruct。



    } catch (InstantiationException e) {

        e.printStackTrace();

    } catch (IllegalAccessException e) {

        e.printStackTrace();

    } catch (InvocationTargetException e) {

        e.printStackTrace();

    } catch (NoSuchMethodException e) {

        e.printStackTrace();

    }

    return instance;

}

//获取容器中的Bean

 public Object getBean(String beanName) {

        if (!beanDefinitionMap.containsKey(beanName)) {

            throw new RuntimeException("不存在该bean" + beanName);

        }

        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        String scope = beanDefinition.getScope();

        if (ConfigurableBeanFactory.SCOPE_SINGLETON.equals(scope)) {

            Object singletonBean = singletonObjects.get(beanName);

            //此处很重要,属性填充的时候,可能不存在,需要重新创建并放入容器缓存

            if (singletonBean == null) {

                singletonBean = createBean(beanName, beanDefinition);

                singletonObjects.put(beanName, singletonBean);

            }

            return singletonBean;

        } else {

            // 原型

            Object prototypeBean = createBean(beanName, beanDefinition);

            return prototypeBean;

        }

    }