springIOC源码解析(六)

来源:互联网 发布:java中执行js代码 编辑:程序博客网 时间:2024/05/23 17:26

咱们接着finishBeanFactoryInitialization()方法讲

// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);

注释写的很清楚了,初始化所有非懒加载的单例bean,咱们进去看看怎么做的

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        // Initialize conversion service for this context.        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {            beanFactory.setConversionService(                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));        }        // Register a default embedded value resolver if no bean post-processor        // (such as a PropertyPlaceholderConfigurer bean) registered any before:        // at this point, primarily for resolution in annotation attribute values.        if (!beanFactory.hasEmbeddedValueResolver()) {            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {                @Override                public String resolveStringValue(String strVal) {                    return getEnvironment().resolvePlaceholders(strVal);                }            });        }        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        for (String weaverAwareName : weaverAwareNames) {            getBean(weaverAwareName);        }        // Stop using the temporary ClassLoader for type matching.        beanFactory.setTempClassLoader(null);        // Allow for caching all bean definition metadata, not expecting further changes.        beanFactory.freezeConfiguration();        // Instantiate all remaining (non-lazy-init) singletons.        beanFactory.preInstantiateSingletons();    }

通过注释能知道是在最后一行初始化bean的,咱们进去看看

public void preInstantiateSingletons() throws BeansException {        if (this.logger.isDebugEnabled()) {            this.logger.debug("Pre-instantiating singletons in " + this);        }        // Iterate over a copy to allow for init methods which in turn register new bean definitions.        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);        // Trigger initialization of all non-lazy singleton beans...        for (String beanName : beanNames) {            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {                if (isFactoryBean(beanName)) {                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);                    boolean isEagerInit;                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {                            @Override                            public Boolean run() {                                return ((SmartFactoryBean<?>) factory).isEagerInit();                            }                        }, getAccessControlContext());                    }                    else {                        isEagerInit = (factory instanceof SmartFactoryBean &&                                ((SmartFactoryBean<?>) factory).isEagerInit());                    }                    if (isEagerInit) {                        getBean(beanName);                    }                }                else {                    getBean(beanName);                }            }        }        // Trigger post-initialization callback for all applicable beans...        for (String beanName : beanNames) {            Object singletonInstance = getSingleton(beanName);            if (singletonInstance instanceof SmartInitializingSingleton) {                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;                if (System.getSecurityManager() != null) {                    AccessController.doPrivileged(new PrivilegedAction<Object>() {                        @Override                        public Object run() {                            smartSingleton.afterSingletonsInstantiated();                            return null;                        }                    }, getAccessControlContext());                }                else {                    smartSingleton.afterSingletonsInstantiated();                }            }        }    }

看这里的getBean()方法,很眼熟有没有,进去看看

public Object getBean(String name) throws BeansException {        return doGetBean(name, null, null, false);    }

前面咱们通过BeanFactory初始化容器之后,就是通过这个方法来获取bean实例的;因此通过ApplicationContext启动容器之后非懒加载的单例bean就被初始化了,当需要的时候从beanDefinition中获取就可以


咱们来总结一下通过ApplitionContext启动容器的过程
1、读取配置文件信息
2、解析配置文件信息,并把bean节点信息(包括bean的关联关系)保存在BeanDefinition中
3、把读取过的bean信息在BeanFactory中注册
4、初始化非懒加载的单例bean
5、调getBean获取对象实例——通过beanName从BeanFactory中获取BeanDefinition得到bean信息


到此IOC容器启动的基本流程已经研究完了,有些同学可能会问看一遍源码有什么用,我觉得原因有三点
1、有利于理解spring中的一下基本概念及原理
2、当出现问题是能意识到问题出在哪,能并快速定位解决问题,而不是只能把错误信息复制到google上去搜
3、学习其代码规范、设计模式及编程思想;spring无疑是java最优秀的框架之一,其编程思想是值得所有人学习研究的


下一章咱们一起研究aop的源码!

0 0
原创粉丝点击