sping4.1.x IOC容器资源Bean注册流程详解
编写测试类:
package cn.smallbug.spring.testioc; public interface PersonService { public void save(); }
public class PersonServiceImpl implements PersonService { public PersonServiceImpl(){ System.out.println("3333333333333"); } @Override public void save() { System.out.println("person save!"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <bean id="personService" class="cn.smallbug.spring.testioc.PersonServiceImpl"></bean> </beans>
package cn.smallbug.spring.testioc; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Testioc { @Test public void test01() { ApplicationContext context = // new FileSystemXmlApplicationContext(// "E:/eclipseWorkspace/WorkSpace01/spring/src/test/resources/testioc.xml"); PersonService service = (PersonService) context.getBean("personService"); service.save(); } }
<1>继承
接口继承
实体
<2>流程
定位资源:
类:FileSystemXmlApplicationContext
方法:Constructor
1) setConfigLocations(configLocations); //设置资源地址字符串(XML文件地址)
2) refresh(); //调用基类的refresh()方法
类:AbstractApplicationContext
方法:refresh()
3) obtainFreshBeanFactory()
方法:obtainFreshBeanFactory
4) refreshBeanFactory()
类:AbstractRefreshableApplicationContext
方法:refreshBeanFactory()
5) createBeanFactory(); //创建DefaultListableBeanFactory对象,作为实际的IOC容器
6) loadBeanDefinitions(beanFactory); //模板方法模式调用子类实现
类:AbstractXmlApplicationContext
方法:loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
7) new XmlBeanDefinitionReader(beanFactory); //创建读取资源的Reader类
8) loadBeanDefinitions(beanDefinitionReader);
方法:loadBeanDefinitions(XmlBeanDefinitionReader reader)
9) reader.loadBeanDefinitions(configLocations);//这个方法有两种情况,分别处理Resource资源和String资源
类:AbstractBeanDefinitionReader
方法:loadBeanDefinitions(String... locations)
10) for (String location : locations) {
counter += loadBeanDefinitions(location);
}
方法:loadBeanDefinitions(String location)
11) return loadBeanDefinitions(location, null);
方法:loadBeanDefinitions(String location, Set<Resource> actualResources)
12) ResourceLoader resourceLoader = getResourceLoader();//该对象将String转化为Resource
13) ((ResourcePatternResolver) resourceLoader).getResources(location);//转换资源AbstractApplicationContext
类:AbstractApplicationContext
方法:getResources(String locationPattern)
14) return this.resourcePatternResolver.getResources(locationPattern);
类:PathMatchingResourcePatternResolver
方法:getResources(String locationPattern)
15) return new Resource[] {getResourceLoader().getResource(locationPattern)};
类:DefaultResourceLoader
方法:getResource(String location)
16) return getResourceByPath(location);
类:FileSystemXmlApplicationContext
方法:getResourceByPath(String path)
17) return new FileSystemResource(path);//创建一个Resource并返回
加载资源:
类:AbstractBeanDefinitionReader
方法:loadBeanDefinitions(String location, Set<Resource> actualResources)
18) int loadCount = loadBeanDefinitions(resources);
方法:loadBeanDefinitions(Resource... resources)
19) for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);//循环加载注册资源
}
类:XmlBeanDefinitionReader
方法:loadBeanDefinitions(EncodedResource encodedResource)
20) InputStream inputStream = encodedResource.getResource().getInputStream();//创建IO流
21) return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
方法:doLoadBeanDefinitions(InputSource inputSource, Resource resource)
22) Document doc = doLoadDocument(inputSource, resource);//将读入的资源转化为Docuemnt
23) return registerBeanDefinitions(doc, resource);
方法:registerBeanDefinitions(Document doc, Resource resource)
24) BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
25) documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
类:DefaultBeanDefinitionDocumentReader
方法:registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
26) Element root = doc.getDocumentElement();将Document转化为Element
27) doRegisterBeanDefinitions(root);
方法:doRegisterBeanDefinitions(Element root)
28) this.delegate = createDelegate(getReaderContext(), root, parent);//很重要,解析Element使用的就是这个对象
29) parseBeanDefinitions(root, this.delegate);
方法:parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)
30) NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {//逐条解析,对应每一个Bean
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);//解析import,alias,bean,beans
}
else {
delegate.parseCustomElement(ele);
}
}
}
方法:parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)
31) processBeanDefinition(ele, delegate);//解析bean
方法: processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)
32) BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
方法: parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)
33) String id = ele.getAttribute(ID_ATTRIBUTE);//读取ID
34) String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);//读取name
35) AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);//进一步解析
36) return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);//将解析好的BeanDefinition装入BeanDefinitionHolder
注册资源
类:DefaultBeanDefinitionDocumentReader
方法:processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)
37) BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
类:DefaultListableBeanFactory
方法:registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
38) this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
this.beanDefinitionMap.put(beanName, beanDefinition);
定义如下:
/** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
/** List of names of manually registered singletons, in registration order */
private final Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
可见最终bean资源其实是注册到了BeanFactory子类的一个ConcurrentHashMap中
上一篇: 大牛_博客Java方面链接总结
下一篇: java精品博客收集