Spring的IOC容器的核心实现原理是什么

(一共13个方法,看一下Spring IoC 源码,类、方法、注解)

1.准备工作

在Spring 开始启动的时候,它会跳到一个refresh方法里面去,refresh包含了13个核心方法,这些方法最开始的时候,会提供一些刷新前的准备工作,比如说会创建某些集合对象,设置某些基本的特征类,

然后会去创建好容器对象,然后会把我们需要创建对象的一些定义信息加载到容器中,用XML或者注解的方式,XML或者注解会通过他们独特的解析方式把它转换成对应的BeanDefinition(一个接口),

然后会放到一个Map容器中,叫BeanDefinitionMap,当拿到完整的BeanDefinitionMap之后,就可以进行后续的实例化过程了

注1:准备工作中有个重要的组件叫监听器,这里用到了观察者模式,里面有广播器Multicaster、有监听器Listener、还有发布事件Event

注2:Spring也会提供容器的扩展性,所以在BeanDefinition创建完成之后,会对Beanfactory中的一些信息做出某些修改工作(比如数据源配置,用占位符方式;那么在BeanfactoryPostProcess实现里面进行扩展实现,把这些占位符替换成我们需要的实际的值)

2.以上准备工作做完之后:

1)会通过反射的方式从BeanDefinition中拿到对应的信息,然后进行实例化;

2)实例化完成之后,会进行相关的属性设置工作,包括某些Bean对象的扩展工作,以及我的使用过程

3)当我用完了,这个对象已经不需要的时候,我会关闭我的容器,关闭容器的时候会触发销毁过程,同时会触发某些事件告诉Spring以什么方式来结束销毁,包括清空对应的缓存信息

 容器中bean的实例化:当所有beanDefinition对象都已经准备好之后,spring框架会在容器初始化时就调用getBean—> doGetBean—> createBean—> doCreateBean这个流程将所有的bean对象进行初始化过程,所有的bean对象最后存储的容器是DefaultListableBeanFactory;

beanPostProcessor(bean的实例化阶段):bean对象的后置处理,在bean真正初始化之前,我们可以通过实现这个接口对bean的有关属性,或者方法进行修改,在spring中有AOP就是通过beanPostProcessor在bean创建之后创建bean的代理对象;

 对于spring容器启动到bean初始化整个过程,spring都统一将这个过程放到了AbstractApplicationContext.refresh()这个方法中,读懂这个方法的核心步骤,也就理解了spring容器是如何启动并加载bean对象的;源码如下

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            /**
             * 做容器刷新前的准备工作
             * 1、设置容器的启动时间
             * 2、设置活跃状态为true
             * 3、设置关闭状态为false
             * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中
             * 5、准备监听器和事件的集合对象,默认为空的集合
             */

            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 创建容器对象:DefaultListableBeanFactory
            // 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // beanFactory的准备工作,对各种属性进行填充
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 调用各种beanFactorypostProcessor进行beanDefinition的增强处理
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 注册beanPostprocessor,这里只是注册功能,真正调用的是getBean方法(核心四步:getBean——>doGetBean——>createBean——>doCreateBean)
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的时候通过国际化的代码重点讲
                initMessageSource();

                // Initialize event multicaster for this context.
                // 初始化事件监听多路广播器
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 留给子类来初始化其他的bean
                onRefresh();

                // Check for listener beans and register them.
                // 在所有注册的bean中查找listener bean,注册到消息广播器中
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 初始化剩下的单实例(非懒加载的)
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                // 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
                destroyBeans();

                // Reset 'active' flag.
                // 重置active标志
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

 

 总结:

1.控制反转:原来的对象是由使用者来进行控制,有了Spring之后,可以把整个对象交给Spring来帮我们进行管理

2.容器:存储对象,使用map结构来存储,在Spring中一般存在三级缓存,singletonObject存放完整的bean对象,整个bean的生命周期,从创建到使用再到销毁的过程全部都是由容器来管理

3.DI:依赖注入,把对应的属性的值注入到具体的对象中,比如@Autowired、@Resource完成属性的注入

大致流程为:

1.IOC容器从xml,注解等地方获取类的信息。
2.将类的信息封装成BeanDefinition
3.beanFactoryPostProcessor前置处理
4.ioc容器获取类信息通过反射进行实例化
5.执行实例化
6.执行初始化逻辑(填充属性(populateBean)->执行aware接口方法->beanPostProcessor:before->init-method->beanPostProcessor:after)

 

posted @ 2024-01-29 23:37  初仰  阅读(6)  评论(0)    收藏  举报