ZPY博客

spring创建对象的底层原理

1.spring核心容器 
spring核心容器理论很简单,就是一个大工厂,所有的对象都会被当成管理对象–spring把所有的对象都称为Bean。
不同于以前的JavaBean的规范,只要是一个类,spring就管理该类,并当成Bean来处理。
对于spring框架而言,一切对象都称为Bean。
那么,spring是怎么来管理这么多Bean的?是通过配置文件(或者注解)。
2.使用配置文件管理Bean的原理 
spring配置文件一般均为如下格式

<bean id="user" class="indi.spring.po.User"></bean>
<bean id="userDao" class="indi.spring.dao.UserDao">
    <property name="use" ref="user"></property>
</bean>

实际上,配置spring容器中Bean的默认以反射调用该类的无参构造方法创建对象
以下面元素为例

//首先会先通过dom4j解析该id属性得到该id字符串 
//然后在解析class属性得到class的全名 
String idStr=…; 
String classStr=…; 
//通过反射创建实体对象 
Class clazz=Class.forName(classStr); 
Object obj=clazz.newInstance(); 
//spring容器存放该对象,以id为key 
container.put(idStr,obj);

以上是最基本的反射代码(实际上更完善一些),spring框架就通过class创建java对象,以id作为key,最后存放到了spring容器中,这个java对象就称为了spring容器中的Bean。

<bean id="userDao" class="indi.spring.dao.UserDao">
    <property name="use" ref="user"></property>

该ref为user的bean一旦创建,spring就会去寻找property元素执行setter方法

String nameStr=...;//根据配置文件解析出该name属性值,得到字符串user
String refStr=...;//根据配置文件解析出该bean名称,得到字符串user
//拼接set方法,得到该method为getUser
String methodName="set"+nameStr.substring(0, 1).toUpperCase()+nameStr.substring(1);
//获取id为user的bean,之前有创建
Object paramBean=container.get(refStr);
//clazz创建的UserDao的class对象(创建方法与上述User对象创建一致)
Method method=clazz.getMethod(methodName,paramBean.getClass);
//obj为UserDao的对象(也就是clazz的newInstance)
method.invoke(obj,paramBean)

spring通过<property>元素里面的name属性来决定调用哪个set方法,然后根据ref来决定传入参数 接下来,程序就可以通过spring容器来访问容器中的bean了,spring容器提供了ApplicationContext接口。有两个实现类,建议使用ClassPathXmlApplicationContext来创建对象,需要将配置文件路径传递进去。

ApplicationContext ac=new ClassPathXmlApplicationContext("a.xml");
//需要将配置文件中对应bean的id传递进去
User user=(User)ac.getBean("user");
//该方法需要传递id值与class名,不过不需要强制转换类型
User user2=ac.getBean("user",User.class);