Spring源码剖析1:初探Spring IOC核心流程

  • 时间:
  • 浏览:0
  • 来源:神彩UU直播现场_彩神UU直播现场官方

22

    String[] aliases = definitionHolder.getAliases();

21

}

}

        return parsePropertySubElement(subElement, bd);

15

19

    for (int i = 0; i < nl.getLength(); i++) {

</bean>

26

    }

10

16

1. 初始化

    else if (subElement != null) {

41

48

10

4

4

9

    setConfigLocations(configLocations);

5

9

14

21

20

1

14

8

49

        catch (BeansException ex) {

}

7

2

                    "<constructor-arg> element";

43

40

13

45

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

16

2

15

13

1

    }

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

10

    else if (hasValueAttribute) {

15

    initBeanDefinitionReader(beanDefinitionReader);

12

17

    }

        final Object[] args) {

}

    bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

7

27

    Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

13

6

        }

    }

    int loadCount = loadBeanDefinitions(resources);

23

12

在完成初始化的过程后,Bean们就在BeanFactory中蓄势以待地等调用了。下面通过有另3个具体的例子,来完整篇 地学习一下初始化过程,同类当加载下面有另3个bean:

            BeanDefinitionReaderUtils.registerBeanDefinition(

7

    if (mbd.isSingleton()) {

18

            else {

2

1

        if (!StringUtils.hasText(refName)) {

    for (Resource resource : resources) {

        }

1

17

        prepareBeanFactory(beanFactory);

7

            registerBeanPostProcessors(beanFactory);

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)

9

        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

5

保存配置位置,并刷新

在调用ClassPathXmlApplicationContext后,先会将配置位置信息保存到configLocations,供上端解析使用,后来 ,会调用AbstractApplicationContext的refresh方式进行刷新:

4

8

        BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)

        for (String alias : aliases) {

25

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

5

21

}

42

        }

1

}

36

        <list>

                    "<property> element for property '" + propertyName + "'" :

9

8

16

11

5

16

3

15

18

12

    try {

    }

20

7

15

        catch (BeanDefinitionStoreException ex) {

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh,

15

4

19

        prepareRefresh();

public static void registerBeanDefinition(

创建载入BeanFactory

35

    if (instanceWrapper == null) {

3

1

    super(parent);

11

27

    parseQualifierElements(ele, bd);

26

本步骤中,通过parseBeanDefinitionElement将XML的元素解析为BeanDefinition,或者占据 BeanDefinitionHolder中,或者再利用BeanDefinitionHolderBeanDefinition注册,实质后来 我把BeanDefinition的实例put进BeanFactory中,和上端将完整篇 的介绍解析和注册过程。

        RuntimeBeanReference ref = new RuntimeBeanReference(refName);

20

7

        counter += loadBeanDefinitions(resource);

14

    parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

    <property name="instruments">

    String beanName = definitionHolder.getBeanName();

14

19

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {

4

12

7

3

5

            finishBeanFactoryInitialization(beanFactory);

2

25

解决属性的值

18

5

10

17

3

    BeanWrapper instanceWrapper = null;

24

    if (aliases != null) {

protected final void refreshBeanFactory() throws BeansException {

21

            if (delegate.isDefaultNamespace(ele)) {

46

16

8

    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

3

18

7

    }

public AbstractBeanDefinition parseBeanDefinitionElement(

11

     throws BeansException, IOException {

13

        TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));

2

大致单步跟了下Spring IOC的初始化过程,整个脉络很庞大,初始化的过程主要后来 我读取XML资源,并解析,最终注册到Bean Factory中

public void refresh() throws BeansException, IllegalStateException {

14

23

22

        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

    parsePropertyElements(ele, bd);

2

    }

12

本文大致地介绍了IOC容器的初始化过程,只列出了比较重要的过程和代码,都也能从中看出IOC容器执行的大致流程。

            onRefresh();

        throws BeanDefinitionStoreException {

    }

        Node node = nl.item(i);

9

13

20

11

18

}

16

public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {

33

            destroyBeans();

14

14

13

23

当完成初始化IOC容器后,机会bean没办法 设置lazy-init(延迟加载)属性,没办法 bean的实例就会在初始化IOC完成后来 ,及时地进行初始化。初始化后会先建立实例,或者根据配置利用反射对实例进行进一步操作,具体流程如下所示:

            invokeBeanFactoryPostProcessors(beanFactory);

28

4

}

            }

5

下面对每一步的关键的代码进行完整篇 分析:

            error(elementName + " contains empty 'ref' attribute", ele);

3

        if (exposedObject != null) {

2

注入bean的属性

注入bean的属性过程函数调用栈如下所示:

        ref.setSource(extractSource(ele));

        }

解决XML每个元素

            }

31

    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

                    bdHolder.getBeanName() + "'", ele, ex);

38

微信公众号【Java技术江湖】一位阿里 Java 工程师的技术小站。(关注公众号后回复”Java“即可领取 Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容宽裕,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java进程员面试指南等干货资源)

            registerListeners();

1

12

创建解决每有另3个resource

        throws BeanDefinitionStoreException {

47

创建bean的实例

创建bean的实例过程函数调用栈如下所示:

}

    parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

        return valueHolder;

2

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {

     throws BeanDefinitionStoreException {

在创建bean和注入bean的属性时,不是在doCreateBean函数中进行的,大伙儿儿 重点看下:

    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

22

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,

1

解析和注册bean

19

26

5

29

500

5

    if (bdHolder != null) {

24

24

18

17

22

        try {

6

4

1

            throw ex;

1

6

    }

3

                bdHolder, getReaderContext().getRegistry());

加载需要要读取、解析、注册bean,同类 过程具体的调用栈如下所示:

        instanceWrapper = createBeanInstance(beanName, mbd, args);

3

19

    int counter = 0;

6

25

3

注册过程中,最核心的一句后来 我:this.beanDefinitionMap.put(beanName, beanDefinition),也后来 我说注册的实质后来 我以beanName为key,以beanDefinition为value,将其put到HashMap中。

19

    AbstractBeanDefinition bd = createBeanDefinition(className, parent);

17

    String elementName = (propertyName != null) ?

            initMessageSource();

14

    if (refresh) {

        refresh();

9

18

2

        }

        return ref;

创建XMLBeanDefinitionReader

27

            cancelRefresh(ex);

            registry.registerAlias(beanName, alias);

10

23

18

        }

}

26

        valueHolder.setSource(extractSource(ele));

6

15

    if (hasRefAttribute) {

24

500

16

3

16

    NodeList nl = root.getChildNodes();

    this.beanDefinitionMap.put(beanName, beanDefinition);

1

15

    loadBeanDefinitions(beanDefinitionReader);

11

    DefaultListableBeanFactory beanFactory = createBeanFactory();

8

17

4

4

            postProcessBeanFactory(beanFactory);

8

    }

        try {

}

6

            getReaderContext().error("Failed to register bean definition with name '" +

    Assert.notNull(resources, "Resource array must not be null");

            <ref bean="piano"/>

    loadBeanDefinitions(beanFactory);

        populateBean(beanName, mbd, instanceWrapper);

10

13

6

            finishRefresh();

    </property>

10

9

解决每个Bean的元素

13

        if (node instanceof Element) {

            exposedObject = initializeBean(beanName, exposedObject, mbd);

                parseDefaultElement(ele, delegate);

4

        }

6

25

            <ref bean="saxophone"/>

        String refName = ele.getAttribute(REF_ATTRIBUTE);

8

6

转自:http://www.importnew.com/19243.html

    parseConstructorArgElements(ele, bd);

17

3

            Element ele = (Element) node;

11

6

10

2

    parseMetaElements(ele, bd);

37

    }

10

7

44

5

7

8

    return counter;

39

6

    synchronized (this.startupShutdownMonitor) {

32

7

4

9

        </list>

5

8

<bean id="XiaoWang" class="com.springstudy.talentshow.SuperInstrumentalist">

        Element ele, String beanName, BeanDefinition containingBean) {

}

}

    Object exposedObject = bean;

            initApplicationEventMulticaster();

9

8

理解了以上有另3个过程,大伙儿儿 就都也能此人 实现有另3个简单的Spring框架了。于是,我根据此人 的理解实现了有另3个简单的IOC框架Simple Spring,有兴趣都也能看看。

20

    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

34

28

    }

        ApplicationContext parent) throws BeansException {

public int loadBeanDefinitions(String location, Set<Resource> actualResources)

17

12

                delegate.parseCustomElement(ele);

12

        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

2

接下来的文章会更加深入剖析Bean容器何如解析xml,注册和初始化bean,以及何如获取bean实例等完整篇 的过程。

        }

11

11