Spring源码之ContextLoaderListener(3)

本文更应该是bean定义和bean注册了,但是为了都是在Spring启动的时候执行的ContextLoaderListener,所以标题名字就是继续ContextLoaderListener了。

还是DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root);
核心方法this.parseBeanDefinitions(root, this.delegate);
如何使Spring的默认标签执行this.parseDefaultElement(ele, delegate);

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")) {
        //处理bean的方法,传入的是BeanDefinitionParserDelegate
            this.processBeanDefinition(ele, delegate);
        } else if(delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }

看如何读取的bean标签:

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

    }

其实还是委托给了BeanDefinitionParserDelegate

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {//containingBean传入的是null
        String id = ele.getAttribute("id");
        String nameAttr = ele.getAttribute("name");
        ArrayList aliases = new ArrayList();
        if(StringUtils.hasLength(nameAttr)) {
        //name属性值用,;隔开就是别名啊
            String[] beanName = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
            aliases.addAll(Arrays.asList(beanName));
        }
    //有Id直接用作beanName
        String beanName1 = id;
        if(!StringUtils.hasText(id) && !aliases.isEmpty()) {
        //id属性值没有值,就用上面别名的第一个值作为beanName
            beanName1 = (String)aliases.remove(0);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("No XML \'id\' specified - using \'" + beanName1 + "\' as bean name and " + aliases + " as aliases");
            }
        }

        if(containingBean == null) {
        //保证beanName和别名都不会存在,即都是唯一的
        //然后将beanName和alias都放入到成员变量HashSet
        //这个成员变量包含所有bean的beanName和aliases哈
            this.checkNameUniqueness(beanName1, aliases, ele);
        }
        AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName1, containingBean);
        if(beanDefinition != null) {
            if(!StringUtils.hasText(beanName1)) {
                try {
                    if(containingBean != null) {
                        beanName1 = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
                    } else {
                        beanName1 = this.readerContext.generateBeanName(beanDefinition);
                        String aliasesArray = beanDefinition.getBeanClassName();
                        if(aliasesArray != null && beanName1.startsWith(aliasesArray) && beanName1.length() > aliasesArray.length() && !this.readerContext.getRegistry().isBeanNameInUse(aliasesArray)) {
                            aliases.add(aliasesArray);
                        }
                    }

                    if(this.logger.isDebugEnabled()) {
                        this.logger.debug("Neither XML \'id\' nor \'name\' specified - using generated bean name [" + beanName1 + "]");
                    }
                } catch (Exception var9) {
                    this.error(var9.getMessage(), ele);
                    return null;
                }
            }

            String[] aliasesArray1 = StringUtils.toStringArray(aliases);
            return new BeanDefinitionHolder(beanDefinition, beanName1, aliasesArray1);
        } else {
            return null;
        }
    }

有必要提一下这个方法是返回的BeanDefinitionHolder,hold的对象是BeanDefinition哈,从该方法可以知道每个bean标签对应一个BeanDefinitionHolder,每个holder中都有一个BeanDefinition

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
        this.parseState.push(new BeanEntry(beanName));
        try{
        String className = ele.getAttribute("class").trim();
    ex = ele.getAttribute("parent");
    //通过className和parent属性来构建一个GenericBeanDefinition对象
    AbstractBeanDefinition bd = this.createBeanDefinition(className, ex);
    //bean标签上的属性 init-method destroy-method factory-method 
    //factory-bean abstract scope autowire lazy-init //depends-on autowire-candidate primary dependency-check 
    //总之就是调用bd.setXxx(xxx)来填充BeanDefinition而已
            this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
            //处理meta标签
            this.parseMetaElements(ele, bd);
            //处理lookup-method标签
            this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

            this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
            //处理子节点的construct标签
            this.parseConstructorArgElements(ele, bd);
            //处理子节点的property标签
            this.parsePropertyElements(ele, bd);
            //处理qualifier标签
            this.parseQualifierElements(ele, bd);
            bd.setResource(this.readerContext.getResource());
            bd.setSource(this.extractSource(ele));
            AbstractBeanDefinition var7 = bd;
            return var7;
            catch(Exception ex){
                xxxxx
            }finally{
                this.parseState.pop();
        }       
        return null;
    }

我们回顾一下
第一步:DefaultBeanDefinitionDocumentReader. doRegisterBeanDefinitions(Element root);还是从Root(即beans标签)开始
第二步:解析Element(import bean等标签)
this.processBeanDefinition(ele, delegate);,this完全委托给了delegate完成装在beanDefinition和注册

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}

a)在通过解析bean(以bean为例子)标签设置BeanDefinition的各个属性,然后连同beanName和别名通过构造函数一起放到BeanDefinitionHolder中。
b)注册beanDefinition和alias,注册器就是DefaultListableBeanFactory工厂其实就是跟成员map或者list添加一个值或者多个值
c)注册beanDefinitioin即给其成员变量beanDefinitionMap = new ConcurrentHashMap(256);
添加一个keybeanName,value为BeanDefinition的值
同时给另一个成员beanDefinitionNames = new ArrayList(256);
添加一个beanName值
d)注册别名
DefaultListableBeanFactory的父类SimpleAliasRegistry
aliasMap = new ConcurrentHashMap(16);
key是alias value是beanName
e)有哪些bean的引用,继承了那些bean
到这里一个bean标签转换成BeanDefinition再到注册算是完成了。
还记得这篇博文是那个方法进来的吗?哈哈

wax.refresh()方法的ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

public void refresh() throws BeansException, IllegalStateException {
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
 }

obtainFreshBeanFactory()方法内部,给AbstractRefreshableApplicationContext的beanFactory赋值之前就是前面所有看到的、讲解过的代码

protected final void refreshBeanFactory() throws BeansException {
            DefaultListableBeanFactory ex = this.createBeanFactory();
            ex.setSerializationId(this.getId());
            this.customizeBeanFactory(ex);
            this.loadBeanDefinitions(ex);//这一步是之前所讲
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = ex;//获取工厂
            }
    }

在代码中跳来跳去,原来只是为了获取DefaultListableBeanFactory

oh,my god!!这一行代码中,读取了配置文件,获取了Document的root节点、找到bean标签
转化成了BeanDefinition 在和beanname以及别名组装到了BeanDefintionHolder中,在将BeanDefinition注册到工厂中,别名也注册进去(工厂的父类)SimpleAliasRegistry。

在看wac.refresh()全景

            this.prepareRefresh();
            //已读
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //准备在设置部分信息到BeanFactory
            this.prepareBeanFactory(beanFactory);
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
        }

看下prepareBeanFactory,它set了一堆对象,并往BeanFactory注册了几个跟环境有关的对象,这里说的注册还是给成员singletonObjects = new ConcurrentHashMap(256);添加key和value对

DefaultListableBeanFactory的三个成员有值了,下面是所有成员变量,先看下,后边都会用到。

private static Class<?> javaUtilOptionalClass = null;
    private static Class<?> javaxInjectProviderClass = null;
    private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories;
    private String serializationId;
    private boolean allowBeanDefinitionOverriding = true;
    private boolean allowEagerClassLoading = true;
    private Comparator<Object> dependencyComparator;
    private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
    private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap(16);
    // applicationContext.xml中bean key:test value  
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap(64);
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap(64);
    //
    private volatile List<String> beanDefinitionNames = new ArrayList(256);
    private volatile Set<String> manualSingletonNames = new LinkedHashSet(16);
    private volatile String[] frozenBeanDefinitionNames;
    private volatile boolean configurationFrozen = false;
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        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.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        if(beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if(!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if(!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if(!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

到这里,只是一个bean标签的解析,还有import ,甚至是自定义标签 tx 等没有讲,但是现在已经有些晕乎了。。。

猜你喜欢

转载自blog.csdn.net/mayongzhan_csdn/article/details/62037161