具体代码如下:
java bean:
package com.hewei.spring.core;
import java.util.Map;
public class StrongTypeBean {
private Map<String,Float> accounts;
public Map<String, Float> getAccounts() {
return accounts;
}
public void setAccounts(Map<String, Float> accounts) {
this.accounts = accounts;
}
}
spring 配置文件:
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd”>
<bean id=”foo” class=”com.hewei.spring.core.StrongTypeBean”>
<property name=”accounts”>
<map>
<entry key=”one” value=”9.99″/>
<entry key=”two” value=”2.75″/>
<entry key=”six” value=”3.99″/>
</map>
</property>
</bean>
</beans>
测试用例:
package com.hewei.spring.core;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class StrongTypeTest extends TestCase {
StrongTypeBean bean = null;
public void setUp() {
ApplicationContext context = new FileSystemXmlApplicationContext(
“conf/applicationContext.xml”);
bean = (StrongTypeBean) context.getBean(“foo”);
}
public void test() {
Map<String, Float> accounts = bean.getAccounts();
for(String key:accounts.keySet()){
System.out.println(key);
}
}
}
通过阅读spring源代码及调试,发现spring生成一个bean,基本上可以分为2个步骤:1,BeanFactory读取xml配置文件,进行解析,然后通过BeanDefinitationReader来获取各个bean的定义,并且将这些定义注册在BeanFactory中.
解析Bean 定义的过程:
AbstractApplicationContext里的loadBeanDefinitations方法,会接收一个BeanFactory对象作为参数,然后使用这个BeanFactory来生成一个BeanDefinitaionReader(BeanDefinitationReader使用这个BeanFactoy来存放解析出来的BeanDefinitaion)。
在生成reader后,Context将配置文件的路径或者resouce传递给reader,reader调用自身的loadBeandefinitations来解析bean 定义。在XmlBeanDefinitationReader中,会将resouce封装成EncodeResource(解决xml文件的编码问题)传递给loadBeanDefinitations方法,此方法调用doLoadBeanDefinitations方法,后者会将使用代表配置文件的resouce来生成一个dom模型的Document,为了从这个Document中解析bean definitation,reader会生成一个BeanDefinitionDocumentReader 对象(将真正的解析工作委托这个DocumentReader来进行),然后调用这个对象的registerBeanDefinitions(Document doc, XmlReaderContext readerContext)方法。
在registerBeanDefinitions方法中,会生成一个BeanDefinitionParserDelegate 对象,从名字可以看出,这个一个代理类,DocumentReader会遍历整个doc,然后将每个element给这个ParserDeleagate进行parse,delegate parse后,会返回BeanDefinitationHolder 对象,这个对象包含了该element代表的bean的定义,然后DocumentReader会将返回的BeanDefinitationHolder传递给bean registry(实际使用的就是生成BeanDefinitationReader时传递进来的BeanFactory )来进行保存,以便后续使用这些definitation时,能够直接取来使用。