IOC

整体架构:
Spring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块,如下所示


image

Core Container
Core Container (核心容器)包含Core,Beans,Context和Expression Language模块.
Core和Beans模块是框架的基本部分,提供IOC和依赖注入特性.这里的基础概念的BeanFactory, 它提供对Factory模式经典实现,来消除程序性的单例模式需求,分离出依赖关系和配置
1)Core模块主要包含Spring框架的基本核心工具类,Spring的其他组件都要使用到这个包里的类,Core模块是其他组件的基本核心.
2)Beans模块是所有应用都要用到的,它包含访问配置文件,创建和管理bean以及进行IOC/DI操作相关的所有类.
3)Context模块构建于Core和Beans模块基础之上,提供一种类似于JNDI注册器的框架式对象访问方法.Context模块继承了Beans的特性,为
Spring核心提供了大量扩展,添加了对国际化(如资源绑定),事件传播,资源加载和对Context的透明创建的支持.ApplicationContext接口是Context模块的关键.
4)Expression Language模块提供了一个强大的表达式ko'l语言用于在运行时查询和操纵对象.

IOC,控制反转(Inversion of Control),常见方式依赖注入(Dependency Injection,简称 DI ),还有一种方式为依赖查找.

public static void main(String[] args) throws InterruptedException {
        //启动spring容器,完成spring框架的初始化
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        MyBean myBean = context.getBean("myBean", MyBean.class);
        System.out.println(myBean.getMyName() + "---" + myBean.getMyAge());
        myBean.myHi();
    }

根据以上测试方法,跟读spring源码.

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

创建ClassPathXmlApplicationContext对象时,启动spring容器,初始化spring框架,代码如下:

public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {
        //调用父类的构造方法,初始化成员变量,parent参数为null
        super(parent);
        //设置配置文件位置, ClassPathXmlApplicationContext 的父类AbstractRefreshableConfigApplicationContext 的configLocations属性赋值
        setConfigLocations(configLocations);
        //强制写死的为true
        if (refresh) {
            //刷新应用上下文,实际上即初始化和启动Spring应用上下文(容器),主要逻辑都在这个方法.
            refresh();
        }
    }

下面看refresh()方法

@Override
    public void refresh() throws BeansException, IllegalStateException {
        //线程同步
        synchronized (this.startupShutdownMonitor) {
                // 1、预准备刷新上下文
            prepareRefresh();

            // 2、告诉子类去刷新内部的bean factory,获得刷新的bean factory,最终得到是DefaultListableBeanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 3、预处理bean工厂,为在上下文中使用,注册
            prepareBeanFactory(beanFactory);

                        //4、由子类覆盖该方法做额外的处理,默认spring框架什么也没有做
            postProcessBeanFactory(beanFactory);

            //5、激活各种BeanFactory处理器
            invokeBeanFactoryPostProcessors(beanFactory);

            //6、注册拦截Bean创建的Bean处理器,如果没有bean processors,此步骤什么也不做
            registerBeanPostProcessors(beanFactory);

            //7、在上下文初始化注册messageSource的bean,不同语言环境信息,国际化处理
            initMessageSource();

            //8、在上下文初始化注册applicationEventMulticaster的bean,应用消息广播
            initApplicationEventMulticaster();

            //9、留给子类来初始化其他的bean,默认情况下Spring框架什么也不做
            onRefresh();

            //10、在所有bean中查找listener bean并注册到消息广播中,没有的话就什么也不做;
            registerListeners();

            //11、初始化所有剩下的非延迟初始化的单例bean对象
            finishBeanFactoryInitialization(beanFactory);

            //12、完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知相关事件
            finishRefresh();
        }
    }

1.创建容器对象
ClassPathXmlApplicationContext
AnnotationConfigApplicationContext
XmlWebApplicationContext
2.初始化配置信息setConfigLocations
3.刷新容器refresh()
1)创建工厂bean
容器的beanFactory属性,类型DefaultListableBeanFactory
2)解析xml配置,通过JDK自带的将xml解析为document对象,通过document去获取xml的配置信息.
3)每一个bean定义,对应一个GenericBeanDefinition
通过字符串的全限定类名,获取对应的class
并解析属性等各种值,进行GenericBeanDefinition的赋值


image.png

然后将GenericBeanDefinition 放到DefaultListableBeanFactory 的成员变量beanDefinitionMap中,key为beanname,value为GenericBeanDefinition


image.png

4)通过class获取构造器,并反射创建对象ctor.newInstance(args)
5)反射初始化属性值
6)将对象放入DefaultListableBeanFactory父类的的singletonObjects中key是beanName,value是单例对象
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容