开发中某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。这个过程是怎么实现的,下面就bean.xml文件中的<bean/>做简要分析。

        <bean id=“model” class=“com.shc.ModelFrog”>这个配置代表了一个bean,项目启动后它在spring容器中充当一个对象。<bean/>是在项目启动的时候被加入到spring容器中的,究竟是如何加载进去的?想必大家都熟悉java bean,他是一种规范,spring正是利用这种规范完成了依赖注入的过程。项目启动之初,Spring框架通过反射根据<bean.../>元素的class属性指定的类名(以反射方式来调用该类无参数的构造器)创建了一个Java对象,并以<bean.../>元素的id属性的值为key,将该对象放入Spring容器中—这个对象就成了Spring容器中的Bean。这个bean在spring容器中的存储方式类似于map集合,map<key,bean>,之所以说bean是单例的,因为key是唯一的。

ModelFrog”(解析<bean.../>元素的class属性得到的值)。
以上过程在Spring底层执行的代码过程如下所示:

String idStr=“model”;//解析该<bean.../>元素的id属性得到该字符串值为“model”
 //解析<bean.../>元素的class属性得到的值为”com.shc.ModelFrog”
 String classStr =“com.shc.ModelFrog”;
 Class clazz = Class.forName(classStr);
 Object obj = class.newInstance();
 //Container代表的Spring容器
 container.put(idStr,obj);

       如何完成依赖注入?举例如下

<bean id=“model” class=“com.shc.ModelFrog”>
     //控制调用setGuagua()方法,将容器中的guagua  Bean作为传入的参数
     <property name=“wa” ref=“guagua”/>
 </bean>
 <bean id=“guagua” class=“com.shc.GuaGua”><bean id=“wuwu” class=“com.shc.WuWu”>

上面配置文件中包含一个<property。。。/>子元素,<property.../>子元素通常用于作为<bean.../>元素的子元素,它驱动Spring在底层以反射执行一次setter方法。其中<property。。。/>的name属性值决定执行那个setter方法,而value或者ref决定执行setter方法的传入参数。

1.如果传入参数是基本类型及其包装类、String等类型,则使用value属性指定传入的参数。
2.如果以容器中其他的Bean作为传入参数,则使用ref属性指定传入参数。

该Bean一旦创建处理,Spring会立即根据<property。。。/>子元素来执行setter方法。即:<bean.../>元素驱动Spring调用构造器创建对象;<property。。。/>子元素驱动Spring执行setter方法,这两个步骤是先后执行的,中间几乎没有时间间隔。

以上过程在Spring底层会执行如下代码:

String nameStr =“guagua”;//解析<property。。。/>元素的name属性得到该字符串的值为“guagua”
 String refStr=“guagua”;//解析<property。。。/>元素的ref属性得到该字符串的值为“guagua”。
 String setterName=“set”+nameStr.substring(0,1).toUpperCase()+nameStr.subString(1);//生成将要调用的setter方法名。
 //获取Spring容器中名为refStr的Bean,该Bean将会作为传入参数。
 Object paramBean = container.get(refStr);
 //此处的clazz是前一段反射代码通过<bean.../>元素的class属性得到的.Class对象
 Method setter = clazz.getMethod(setterName,   paramBean.getClass());
 //此处的obj参数是前一段反射代码为<bean.../>元素创建的对象
 setter.invoke(obj, paramBean);

如果此时修改<property name=“wa” ref=“guagua”/>中ref="wuwu",那注入的类将会是WuWu