Spring IoC 源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

参考链接

Spring 启动入口

    ApplicationContext ac = new ClassPathXmlApplicationContext("......")
    ctx.getBean("xxx" , xxx.class);

一般spring demo 都会选择这种启动方式,ClassPathXmlApplicationContext 就是spring源码分析的入口

初始化源码分析

    public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
        private Resource[] configResources;

        // 去除各式各样的初始化函数
        ...

        public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
            super(parent);
            this.setConfigLocations(configLocations);
            if (refresh) {
                // 这个是核心入口,下面的初始化方法也出现了
                this.refresh();
            }
        }

        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核心方法
            this.refresh();
        }
        ...
    }

refresh 方法解析:

    public void refresh() throws BeansException, IllegalStateException {
            Object var1 = this.startupShutdownMonitor;
            synchronized(this.startupShutdownMonitor) {

                // 初始化前的准备操作,验证以及环境设置
                this.prepareRefresh();

                // 初始化BeanFactory,负责bean的生产和管理,是ioc的核心
                ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

                // beanFactory的功能的准备
                this.prepareBeanFactory(beanFactory);

                try {
                    //为子类设置BeanFactory的后置处理器
                    //子类覆盖方法做额外的处理。
                    postProcessBeanFactory(beanFactory);

                    //调用BeanFactoryPostProcessor,激活各种BeanFactory处理器
                    invokeBeanFactoryPostProcessors(beanFactory);

                    // Register bean processors that intercept bean creation.
                    //注册拦截Bean创建的Bean处理器,这里只是注册,真正调用实在getBean的时候。
                    registerBeanPostProcessors(beanFactory);

                    // Initialize message source for this context.
                    //为上下文初始化Message源,国际化处理
                    initMessageSource();

                    // Initialize event multicaster for this context.
                    //初始化应用消息广播器,并放入applicationEventMulticaster bean中
                    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 var9) {
                    // 销毁beans
                    this.destroyBeans();
                    // 取消refresh
                    this.cancelRefresh(var9);
                    throw var9;
                } finally {
                    this.resetCommonCaches();
                }
            }
        }

获取beanfactory:

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
            // refresh beanFactory:参考AbstractRefreshableApplicationContext实现
            this.refreshBeanFactory();

            // 获取beanFactory,留给子类实现
            ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();

            return beanFactory;
        }

refreshBeanFactory 的实现:

    protected final void refreshBeanFactory() throws BeansException {
            // 判断内置beanFactory对象引用
            if (this.hasBeanFactory()) { // 如果以及存在
                this.destroyBeans(); // 销毁关闭
                this.closeBeanFactory();
            }

            try {
                // 重新创建
                DefaultListableBeanFactory beanFactory = this.createBeanFactory();
                beanFactory.setSerializationId(this.getId());
                this.customizeBeanFactory(beanFactory);
                // 加载bean,由子类实现,可参考XmlBeanDefinitionReader实现
                this.loadBeanDefinitions(beanFactory);
                Object var2 = this.beanFactoryMonitor;
                synchronized(this.beanFactoryMonitor) {
                    // 同步赋值
                    this.beanFactory = beanFactory;
                }
            } catch (IOException var5) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
            }
        }

loadBeanDefinitions 的具体实现:
将资源转为BeanDefinition(bean定义实体),结果存放在Map中。

        public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
            return this.loadBeanDefinitions(new EncodedResource(resource));
        }

        public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
            Assert.notNull(encodedResource, "EncodedResource must not be null");

            // xml => resource
            Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
            if (currentResources == null) {
                currentResources = new HashSet(4);
                this.resourcesCurrentlyBeingLoaded.set(currentResources);
            }

            if (!((Set)currentResources).add(encodedResource)) {
                throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
            } else {
                int var5;
                try {
                    InputStream inputStream = encodedResource.getResource().getInputStream();

                    try {
                        InputSource inputSource = new InputSource(inputStream);
                        if (encodedResource.getEncoding() != null) {
                            inputSource.setEncoding(encodedResource.getEncoding());
                        }
                        // 实际上执行bean到resource对象的转换的方法
                        var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                    } finally {
                        inputStream.close();
                    }
                } catch (IOException var15) {
                    throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
                } finally {
                    ((Set)currentResources).remove(encodedResource);
                    if (((Set)currentResources).isEmpty()) {
                        this.resourcesCurrentlyBeingLoaded.remove();
                    }

                }

                return var5;
            }
        }

        // xml 解析
        protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
            try {
                // xml解析转为document
                Document doc = this.doLoadDocument(inputSource, resource);
                // 组装 + 注册(存放在Map)
                return this.registerBeanDefinitions(doc, resource);
            } 
            ...
        }

registerBeanDefinitions 方法解析:

        public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
            // BeanDefinitionDocumentReader 完成定义信息的解析和Bean信息的注册
            BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
            int countBefore = this.getRegistry().getBeanDefinitionCount();
            // 参考:DefaultBeanDefinitionDocumentReader
            documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
            return this.getRegistry().getBeanDefinitionCount() - countBefore;
        }

registerBeanDefinitions的实现:

        public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
            this.readerContext = readerContext;
            this.logger.debug("Loading bean definitions");
            Element root = doc.getDocumentElement();
            this.doRegisterBeanDefinitions(root);
        }

        protected void doRegisterBeanDefinitions(Element root) {
            BeanDefinitionParserDelegate parent = this.delegate;
            // 解析注册
            this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
            if (this.delegate.isDefaultNamespace(root)) {
                String profileSpec = root.getAttribute("profile");
                if (StringUtils.hasText(profileSpec)) {
                    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
                    if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                        return;
                    }
                }
            }

            this.preProcessXml(root);// 自定义标签解析前置处理
            this.parseBeanDefinitions(root, this.delegate); //spring原标签处理
            this.postProcessXml(root);// 自定义标签解析后置处理
            this.delegate = parent;
        }

实际解析大体流程:

     protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
            if (delegate.isDefaultNamespace(root)) {
                NodeList nl = root.getChildNodes();

                for(int i = 0; i < nl.getLength(); ++i) {
                    Node node = nl.item(i);
                    if (node instanceof Element) {
                        Element ele = (Element)node;
                        if (delegate.isDefaultNamespace(ele)) {
                            this.parseDefaultElement(ele, delegate);
                        } else {
                            delegate.parseCustomElement(ele);
                        }
                    }
                }
            } else {
                delegate.parseCustomElement(root);
            }
        }

        private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
            if (delegate.nodeNameEquals(ele, "import")) {
                this.importBeanDefinitionResource(ele);
            } else if (delegate.nodeNameEquals(ele, "alias")) {
                this.processAliasRegistration(ele);
            } else if (delegate.nodeNameEquals(ele, "bean")) {
                // 解析注册
                this.processBeanDefinition(ele, delegate);
            } else if (delegate.nodeNameEquals(ele, "beans")) {
                // 递归
                this.doRegisterBeanDefinitions(ele);
            }
        }

        protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
            BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
            if (bdHolder != null) {
                bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

                try {
                    // 实际注册代码
                    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
                } catch (BeanDefinitionStoreException var5) {
                    this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
                }

                this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
            }

        }

注册bean

    public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
            String beanName = definitionHolder.getBeanName();
            // 注册方法
            registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
            String[] aliases = definitionHolder.getAliases();
            if (aliases != null) {
                String[] var4 = aliases;
                int var5 = aliases.length;

                for(int var6 = 0; var6 < var5; ++var6) {
                    String alias = var4[var6];
                    registry.registerAlias(beanName, alias);
                }
            }
        }

        // BeanFactory 默认实现DefaultListableBeanFactory,实现了BeanDefinitionRegistry
        public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
            ...
            private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
            ...
        }

put 方法:

                if (this.hasBeanCreationStarted()) {
                    Map var4 = this.beanDefinitionMap;
                    synchronized(this.beanDefinitionMap) {
                        this.beanDefinitionMap.put(beanName, beanDefinition);
                        List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                        updatedDefinitions.addAll(this.beanDefinitionNames);
                        updatedDefinitions.add(beanName);
                        this.beanDefinitionNames = updatedDefinitions;
                        if (this.manualSingletonNames.contains(beanName)) {
                            Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                            updatedSingletons.remove(beanName);
                            this.manualSingletonNames = updatedSingletons;
                        }
                    }
                } else {
                    // 最终写入Map
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    this.beanDefinitionNames.add(beanName);
                    this.manualSingletonNames.remove(beanName);
                }

初始化总结:

  1. 初始化的大体流程:资源定位、资源加载、注册
  2. refresh() 是核心函数
  3. beanDefinition最终存于Map

获取bean源码分析

        public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
            return this.doGetBean(name, requiredType, args, false);
        }

        protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
            final String beanName = this.transformedBeanName(name);
            Object sharedInstance = this.getSingleton(beanName);
            Object bean;
            if (sharedInstance != null && args == null) {
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
            } else {
                if (this.isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }

                BeanFactory parentBeanFactory = this.getParentBeanFactory();
                if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                    String nameToLookup = this.originalBeanName(name);
                    if (args != null) {
                        return parentBeanFactory.getBean(nameToLookup, args);
                    }

                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }

                if (!typeCheckOnly) {
                    this.markBeanAsCreated(beanName);
                }

                try {
                    final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                    this.checkMergedBeanDefinition(mbd, beanName, args);
                    String[] dependsOn = mbd.getDependsOn();
                    String[] var11;
                    if (dependsOn != null) {
                        var11 = dependsOn;
                        int var12 = dependsOn.length;

                        for(int var13 = 0; var13 < var12; ++var13) {
                            String dep = var11[var13];
                            if (this.isDependent(beanName, dep)) {
                                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                            }

                            this.registerDependentBean(dep, beanName);
                            this.getBean(dep);
                        }
                    }

                    if (mbd.isSingleton()) {
                        sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                            public Object getObject() throws BeansException {
                                try {
                                    return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                                } catch (BeansException var2) {
                                    AbstractBeanFactory.this.destroySingleton(beanName);
                                    throw var2;
                                }
                            }
                        });
                        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    } else if (mbd.isPrototype()) {
                        var11 = null;

                        Object prototypeInstance;
                        try {
                            this.beforePrototypeCreation(beanName);
                            prototypeInstance = this.createBean(beanName, mbd, args);
                        } finally {
                            this.afterPrototypeCreation(beanName);
                        }

                        bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                    } else {
                        String scopeName = mbd.getScope();
                        Scope scope = (Scope)this.scopes.get(scopeName);
                        if (scope == null) {
                            throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                        }

                        try {
                            Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                                public Object getObject() throws BeansException {
                                    AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                                    Object var1;
                                    try {
                                        var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
                                    } finally {
                                        AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                                    }

                                    return var1;
                                }
                            });
                            bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                        } catch (IllegalStateException var21) {
                            throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
                        }
                    }
                } catch (BeansException var23) {
                    this.cleanupAfterBeanCreationFailure(beanName);
                    throw var23;
                }
            }

            if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
                try {
                    return this.getTypeConverter().convertIfNecessary(bean, requiredType);
                } catch (TypeMismatchException var22) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            } else {
                return bean;
            }
        }

bean 作用域:

  • singleton
  • prototype

bean 加载时机:

  • 延迟加载:第一次getBean的时候,才生成实例
  • 立即加载:在ioc初始化的时候,就生成实例

来源:http://ddrv.cn

赞(1) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring IoC 源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏