spring精选&&收录spring框架源码相关技术文章三个JAVA臭皮匠java

Spring源码解析系列之IOC容器(一)

2018-06-02  本文已影响185人  后厂村老司机

前言

实际上我所有的博客都是原来对原来印象笔记里笔记内容的加工,关于Spring源码自己已经解析了很多遍,但是时间长总是忘记,写一篇博客权当加强记忆,也算再次学习下大师们的设计思想,思考方式。本次源码解析对最底层的如怎么读取xml文件等不做详细解释,只分析关键步骤和思想。

1、Spring整体架构

Spring整体架构
Spring由很多模块组成,我们不可能挨个模块去看源码去分析,看源码本身就是一件及其枯燥乏味的事情。言简意赅,咱们Spring源码解析系列只挑干货,即Core Container模块的IOC依赖注入,AOP模块的面向切面编程,DataAccess模块的Trasactions事务原理和web模块的mvc原理部分。而且分析也尽量偏向重要步骤和思想,而不是干巴巴的啃源码。
源码分析思路:
首先:确定IOC容器做了什么,其实主要是加载和管理bean
然后:找到做这些事情的所有顶层接口
再次:找顶层接口的干不同事情的子类、分析这些子类是做什么的
最后:挑最富有内涵的接口分析其原理和思想,学习他们的设计思路

2、IOC容器

2.1、IOC的概念

IOC即依赖注入、控制反转,两个概念都一样,即把创建Java对象和维持对象的依赖关系的活儿交给Spring来做,把对对象的控制权交给Spring、让对象减少耦合。我们这里把IOC叫做容器,即容纳Java Bean的容器。IOC容器里面所有能提供服务的对象都叫Bean,至于怎么配置Bean这里就不过多赘述了,如果你不知道通过xml和注解配置bean那么你不应该来看源码。

2.2、bean的几种形态

IOC里最重要的概念就是Bean,所有的接口都围绕Bean确立,在真正分析之前我们先看看Bean的几种形态。

<bean id="schedulerFactoryBean"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobFactory" ref="jobFactory"></property>
</bean>
2.3、bean相关重要接口

了解了Bean的几个状态后我们至少能想到几个重要的接口。

2.4、bean创建步骤
2.4.1、创建步骤

上面我们了解了Bean的状态和几个处理Bean的工具,接着我们就看Bean是怎么从概念态变成可用的成熟态的。此处我们先以xml配置的bean为例子。

2.4.2、方法调用链:

为了更好的阅读源码,此处先给出方法调用链


spring方法调用链.png
2.5、源码解读

在开始阅读源码之前我们先来看看重要接口的继承体系(图片来源于网络,侵删)


源码解读开始(以ClassPathXmlApplicationContext为例)

step1:首先创建并初始化一个ClassPathXml的IOC容器

public class HelloProgram {
    public static void main(String[] args) {
        //创建IOC容器
        ApplicationContext context =new ClassPathXmlApplicationContext("beans.xml");
        HelloWorldService service =(HelloWorldService) context.getBean("helloWorldService");
        HelloWorld hw= service.getHelloWorld();
        hw.sayHello();
    }
}
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
 //父容器被设置为Null
        super(parent);
//存储了xml的位置,以便后续获取
        setConfigLocations(configLocations);
        if (refresh) {
//常规操作,初始化容器,如果之前存在就销毁,不存在就创建
            refresh();
    }
}
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 预初始化,设置容器的启动时间、激活标志,初始化和验证一些预定义的属性(有的话)
            prepareRefresh();

            // 初始化BeanFactory,存在则销毁,不存在则创建一个
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 对即将在IOC容器里使用的BeanFactory做一些配置,比如设置类加载器,设置回调方法等
            prepareBeanFactory(beanFactory);

            try {
                // BeanFactory构建完成之后事件,这个方法没有实现,我们可以实现一个。
                postProcessBeanFactory(beanFactory);

                // I执行上面的事件
                invokeBeanFactoryPostProcessors(beanFactory);

                // 在创建Bean过程中注册拦截器,这些个拦截器会在bean成为真正的成熟bean(applicationContext管理的bean)之前调用
                registerBeanPostProcessors(beanFactory);

                // 初始化信息源,信息源bean可以国际化的读取properties文件
                initMessageSource();

                // 初始化事件广播器,对于他内部的监听者applicationListeners,每次事件到来都会一一获取通知(这里使用了观察者模式)
                initApplicationEventMulticaster();

                // 模板方法模式,埋了一个钩子,那些想要实现特殊实例化bean的类可以重写这个方法以实现自己的定制化初始化方案
                onRefresh();

                // 给事件广播器注册一些监听器(观察者模式)
                registerListeners();

                // 完成BeanFacotry的初始化,初始化所有剩余的单例Bean
                finishBeanFactoryInitialization(beanFactory);

                //初始化容器的生命周期事件处理器,并发布容器的生命周期事件 
                finishRefresh();
            }

            catch (BeansException ex) {
                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;
            }
        }
    }

obtainFreshBeanFactory方法调用链

该方法为BeanFactory准备创建Bean的原材料,即BeanDefinition,准备好之后放到一个ConcurrentHashMap里面,key为beanName,value为BeanDefinition

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }
protected final void refreshBeanFactory() throws BeansException {
        //如果已经存在BeanFactory那么就销毁
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            //创建一个默认的BeanFactory,即全功能的那个郭靖!
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            //配置beanFactory的一些定制化属性,如是否允许循环依赖,是否支持definition重写
            customizeBeanFactory(beanFactory);
            //这步就关键了,载入BeanDefinations,给BeanFactory工厂提供创建bean的原材料!
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 为当前工厂创建一个BeanDefinition读取器!
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 根据Contextn的资源对该读取器进行配置,得告诉他去哪读啊,怎么读啊!
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // 这里可以设置一个定制化的Reader
        initBeanDefinitionReader(beanDefinitionReader);
        //此处调用了重载的方法,把已经装饰好的能用的BeanDefinitionReader读取器当参数传了进去
        loadBeanDefinitions(beanDefinitionReader);
    }
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        //这里的reader已经可以正常干活儿了,首先获取bean定义资源
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        //显然这个configRuations我们之前给传了一个路径"bean.xml",所以执行这个重载方法
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
    @Override
    public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        Assert.notNull(locations, "Location array must not be null");
        int counter = 0;
        for (String location : locations) {
            counter += loadBeanDefinitions(location,null);
        }
        return counter;
    }

尼玛,套路好深,一个loadBeanDefinition搞这么多重载方法,擦得,总算到底了

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
        ResourceLoader resourceLoader = getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException(
                    "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
        }

        if (resourceLoader instanceof ResourcePatternResolver) {
            // Resource pattern matching available.
            try {
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                int loadCount = loadBeanDefinitions(resources);
                if (actualResources != null) {
                    for (Resource resource : resources) {
                        actualResources.add(resource);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                }
                return loadCount;
            }
            catch (IOException ex) {
                throw new BeanDefinitionStoreException(
                        "Could not resolve bean definition resource pattern [" + location + "]", ex);
            }
        }
        else {
            // Can only load single resources by absolute URL.
            Resource resource = resourceLoader.getResource(location);
            int loadCount = loadBeanDefinitions(resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }
            return loadCount;
        }
    }

忽略我上面说的到底了,尼玛!!!!到这应该算是到底了吧,这里调用的是XMLBeanDefinitionReader中的loadBeanDefinitions方法,里边用IO流来读取文件

//该方法从我们指定的路径里获取xml的bean!!!
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (logger.isInfoEnabled()) {
            logger.info("Loading XML bean definitions from " + encodedResource.getResource());
        }

        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet<EncodedResource>(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }
        if (!currentResources.add(encodedResource)) {
            throw new BeanDefinitionStoreException(
                    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        }
        try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            finally {
                inputStream.close();
            }
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "IOException parsing XML document from " + encodedResource.getResource(), ex);
        }
        finally {
            currentResources.remove(encodedResource);
            if (currentResources.isEmpty()) {
                this.resourcesCurrentlyBeingLoaded.remove();
            }
        }
    }

好吧,我们接着看下面的载入

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {  
            //此处把xml文件通过IO流读入内存并处理成Document类型,后续就可以通过dom操作了
            Document doc = doLoadDocument(inputSource, resource);
            return registerBeanDefinitions(doc, resource);
        }catch(各种catch){
                      ..........
                }
    }
@SuppressWarnings("deprecation")
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        //创建一个解析Document的BeanDefinitionReader
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        documentReader.setEnvironment(getEnvironment());
        int countBefore = getRegistry().getBeanDefinitionCount();
        //利用DocumentReader注册BeanDefinition
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }
 @Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        logger.debug("Loading bean definitions");
        Element root = doc.getDocumentElement();
        doRegisterBeanDefinitions(root);
    }
protected void doRegisterBeanDefinitions(Element root) {
        //实际上这里的root代表的是<beans>标签
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(getReaderContext(), root, parent);
        if (this.delegate.isDefaultNamespace(root)) {
            String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    return;
                }
            }
        }
        preProcessXml(root);
        parseBeanDefinitions(root, this.delegate);
        postProcessXml(root);

        this.delegate = parent;
    }

下面的方法利用迭代器迭代的把<beans>标签里的元素处理成内存中的BeanDefinition

//真正解析bean标签的方法
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)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }

下面的方法会创建一个BeanDefinitionHolder持有BeanDefinition及名字,别名数组

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        //持有beanName,BeanDefinition和Bean的别名
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // 把beanName-BeanDefinition键值对放到private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);里面
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // 发送注册成功信号,告知容器已经注册好了所有Bean成BeanDefinition了
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

下面这个方法是最终解析xml成BeanDefinition!!!

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
         //获取BeanID
                String id = ele.getAttribute(ID_ATTRIBUTE);
              //获取Bean的名字
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
          //获取bean的所有别名
        List<String> aliases = new ArrayList<String>();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            aliases.addAll(Arrays.asList(nameArr));
        }
        //如果bean没有名字其ID就是他的名字
        String beanName = id;
        if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
            beanName = aliases.remove(0);
            if (logger.isDebugEnabled()) {
                logger.debug("No XML 'id' specified - using '" + beanName +
                        "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            checkNameUniqueness(beanName, aliases, ele);
        }

        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
                        beanName = BeanDefinitionReaderUtils.generateBeanName(
                                beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {
                        beanName = this.readerContext.generateBeanName(beanDefinition);
                        String beanClassName = beanDefinition.getBeanClassName();
                        if (beanClassName != null &&
                                beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                            aliases.add(beanClassName);
                        }
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Neither XML 'id' nor 'name' specified - " +
                                "using generated bean name [" + beanName + "]");
                    }
                }
                catch (Exception ex) {
                    error(ex.getMessage(), ele);
                    return null;
                }
            }
            String[] aliasesArray = StringUtils.toStringArray(aliases);
        //返回BeanDefinationHolder
            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        }
        return null;
    }

Ok以上代码都执行完BeanFactory的原材料算是准备好了,BeanFactory可以拿着这些原材料制作Bean了


prepareBeanFactory方法解析:

该方法为BeanFactory工厂设置类加载器、bean创建监听器、初始化一些IOC容器自带的必须要初始化的Bean

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

finishBeanFactoryInitialization(beanFactory)方法分析

该方法对那些非懒加载(spring默认)的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));
        }

        // 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();
    }

//对配置lazy-init属性Bean的预实例化  
public void preInstantiateSingletons() throws BeansException {  
       if (this.logger.isInfoEnabled()) {  
           this.logger.info("Pre-instantiating singletons in " + this);  
       }  
       synchronized (this.beanDefinitionMap) {  
           for (String beanName : this.beanDefinitionNames) {  
               //获取指定名称的Bean定义  
               RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
               //bean定义为非抽象,单例模式,非懒加载 
               if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {  
                   //如果指定名称的bean是创建容器的Bean  
                   if (isFactoryBean(beanName)) {  
                   //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号 时,获取的是产生容器对象本身,而不是容器产生的Bean.  
                  //调用getBean方法,触发容器对Bean实例化和依赖注入过程  
                       final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);  
                       //标识是否需要预实例化  
                       boolean isEagerInit;  
                       if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {  
                           //一个匿名内部类  
                           isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
                               public Boolean run() {  
                                   return ((SmartFactoryBean) factory).isEagerInit();  
                               }  
                           }, getAccessControlContext());  
                       }  
                       else {  
                           isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();   
                       }  
                       if (isEagerInit) {  
                          //调用getBean方法,触发容器对Bean实例化和依赖注入过程  
                           getBean(beanName);  
                       }  
                   }  
                   else {  
                        //调用getBean方法,触发容器对Bean实例化和依赖注入过程  
                       getBean(beanName);  
                   }  
               }  
           }  
       }  
    }

下面这老长代码我看着都害怕,这个方法是真正创建预实例化的Bean的方法,如果你嫌弃太长了,知道这句话也就差不多够了。这个bean是纯净态无污染的bean哦。我们关注下面方法里的单例模式的bean的创建,和原型模式的bean的创建,直接看关键代码(有注释的)

@SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args,boolean typeCheckOnly) throws BeansException {
        final String beanName = transformedBeanName(name);
        Object bean;
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else {
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dependsOnBean : dependsOn) {
                        if (isDependent(beanName, dependsOnBean)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                        }
                        registerDependentBean(dependsOnBean, beanName);
                        getBean(dependsOnBean);
                    }
                }
                                //
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                else if (mbd.isPrototype()) {
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                beforePrototypeCreation(beanName);
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                finally {
                                    afterPrototypeCreation(beanName);
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        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",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type [" +
                            ClassUtils.getQualifiedName(requiredType) + "]", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

为了上面的代码更容易观察,我们把单例模式bean创建过程提取出来,下面方法的createBean就是真正创建Bean的地方

            if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {  
                //真正创建Bean的地方,要把Bean和BeaNDefination信息传给这个方法
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

下面的代码就是真正执行BeanDefination到Bean实例化的代码,其中populateBean就是依赖注入发生的地方!!!!

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
        /**根据配置的Class信息创建一个实例包裹器,包裹器里包裹着一个实例化的bean,但此bean并没有被赋值**/
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
    //获取到这个没有给属性赋值的纯净Bean
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }
        //如果bean涉及到了循环引用,而且是单例的,而且是在创建过程中,则允许该bean提前曝光,我们下一章会讲解Spring中的循环引用问题
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            ----------打印日志------------
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // 这里把刚刚创建好的bean进行装配,即使bean状态变成成熟态!!!
        Object exposedObject = bean;
        try {
        //使Bean变成成熟态的真正方法,即依赖注入的真正发生地!!!!!
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
        //对bean进行后置处理器处理
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        -----------捕获异常-------
        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        ----------------抛出异常-------------
                    }
                }
            }
        }
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        -------------捕获异常-----------------
        return exposedObject;
    }

总结

经过以上过程,Spring已经启动了一个全新的IOC容器,并把xml里配置的Bean从概念态转变为真正可用的成熟态并放到IOC容器里来管理了。我们可以通过getBean(“beanName”)来获取Bean的成熟态实例!

上一篇下一篇

猜你喜欢

热点阅读