美文网首页
spring IOC初始化

spring IOC初始化

作者: 来搞事情 | 来源:发表于2018-10-09 12:42 被阅读0次

    参考:https://javadoop.com/post/spring-ioc#customizeBeanFactory

    https://javadoop.com/blogimages/spring-context/1.png
    https://javadoop.com/blogimages/spring-context/2.png
        public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent)
                throws BeansException {
    
            super(parent);
            Assert.notNull(paths, "Path array must not be null");
            Assert.notNull(clazz, "Class argument must not be null");
            this.configResources = new Resource[paths.length];
            for (int i = 0; i < paths.length; i++) {
                this.configResources[i] = new ClassPathResource(paths[i], clazz);
            }
            refresh();
        }
    

    1、 首先会初始化一个ApplicationContext,其实是一个BeanFactory,然后调用他的refresh()方法进行初始化

    @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    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.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    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();
                }
            }
        }
    
    

    2、 在refresh方法中会先来个锁,防止在refresh还没有结束的时候又去启动或者销毁容器。

        @Override
        protected final void refreshBeanFactory() throws BeansException {
            if (hasBeanFactory()) {
                destroyBeans();
                closeBeanFactory();
            }
            try {
                DefaultListableBeanFactory beanFactory = createBeanFactory();
                beanFactory.setSerializationId(getId());
                customizeBeanFactory(beanFactory);
                loadBeanDefinitions(beanFactory);
                synchronized (this.beanFactoryMonitor) {
                    this.beanFactory = beanFactory;
                }
            }
            catch (IOException ex) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
            }
        }
    

    3、 之后解析配置文件里面的bean定义,将它包装成一个beandefination保存到beanfactory中,保存在defaultlistablebeanfactory的beandefinationmap中。这里说的 Bean 还没有初始化,只是配置信息都提取出来了。
    4、之后注册一些回调,一些监听器,和一些钩子方法用来扩展

              // 初始化所有的 singleton beans
             //(lazy-init 的除外)
             finishBeanFactoryInitialization(beanFactory);
    

    5、调用finishBeanFactoryInitaization实例化bean
    先进行实例化,如果不存在方法覆写,那么就使用反射进行实例化,否则使用CGLIB。如果有需要覆盖或者动态替换的方法使用Cglib进行动态代理,如果没有需要动态改变的方法那就直接使用反射进行实例化。所谓的动态替换或覆盖的情况,就是使用了replace或者lookup的配置方法。这两个方法的作用就是在调用目标方法的时候,对调用过程进行拦截,调用实现增强功能的拦截器,返回原来实例的代理。

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
       if (System.getSecurityManager() != null) {
          AccessController.doPrivileged(new PrivilegedAction<Object>() {
             @Override
             public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
             }
          }, getAccessControlContext());
       }
       else {
          // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
          invokeAwareMethods(beanName, bean);
       }
    
       Object wrappedBean = bean;
       if (mbd == null || !mbd.isSynthetic()) {
          // BeanPostProcessor 的 postProcessBeforeInitialization 回调
          wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
       }
    
       try {
          // 处理 bean 中定义的 init-method,
          // 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法
          invokeInitMethods(beanName, wrappedBean, mbd);
       }
       catch (Throwable ex) {
          throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
       }
    
       if (mbd == null || !mbd.isSynthetic()) {
          // BeanPostProcessor 的 postProcessAfterInitialization 回调
          wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
       }
       return wrappedBean;
    }
    

    6、之后进行属性的注入,调用回调方法,初始化等等。就是bean生命周期的那几步。
    先实例化,在注入属性
    如果实现了beanNameAware,beanFactoryAware,ApplicationContextAware,进行回调。
    如果实现了BeanPostProcessor接口,调用PostProcessorsBeforeInitialization方法。
    如果bean中定义了init-method或者实现了InitializingBean 接口,调用afterPorpertiesSet方法。
    然后再调用BeanPostProcessor 的 postProcessAfterInitialization 回调
    之后bean就初始化完成了。可以用了。

    销毁的话如果实现了DisposableBean接口,调用destroy方法。如果自定义了destory-method,也会被调用。

    相关文章

      网友评论

          本文标题:spring IOC初始化

          本文链接:https://www.haomeiwen.com/subject/uoeeaftx.html