目录
解析XML配置
首先把一个配置文件封装成一个Resource对象,然后获取Resource对象的输入流,转换成InputSource对象,最后解析成Document对象。
public int loadBeanDefinitions(String location, Set<Resource> actualResources)
throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
//这里的location就是配置文件-applicationContext.xml,转成Resource对象
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//获取resources对象的输入流 再转成JDK的InputSource对象,最后解析成Document
InputStream inputStream = resources.getInputStream();
InputSource inputSource = new InputSource(inputStream);
Document doc = doLoadDocument(inputSource, resource);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
}
applicationContext.xml配置文件解析成Document对象。
bean标签的解析
bean标签的解析,就是默认的处理方法。
获取bean标签的id,并且把beanName赋值为id,设置别名。新建AbstractBeanDefinition对象,通过反射设置beanClass,解析property属性名称和值。
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
//获取bean_id
String id = ele.getAttribute(ID_ATTRIBUTE);
String beanName = id;
AbstractBeanDefinition beanDefinition =
parseBeanDefinitionElement(ele, beanName, containingBean);
String[] aliasesArray = StringUtils.toStringArray(aliases);
//最后返回已经包含了beanName、class对象和一系列方法的BeanDefinition对象
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele,
String beanName, BeanDefinition containingBean) {
String className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
try {
//根据className反射设置setBeanClass和setBeanClassName
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//设置默认方法 setScope、setLazyInit、setAutowireMode...
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//设置property属性 <bean><property name="id" value="1001"></property></bean>
parsePropertyElements(ele, bd);
return bd;
}
return null;
}
- 注册BeanDefinition对象,和component-scan扫描的bean注册一样。向容器中填充对象。不管是XML配置的Bean,还是通过component-scan扫描注册的Bean它们最后都是殊途同归的,会转换成一个BeanDefinition对象。记录着这个Bean对象的属性和方法,最后都注册到容器中,等待在实例化和IOC的时候遍历它们。