依赖注入--如果A依赖于B,则B实例不再由A负责生成,而有容器负责生成,并注入给A实例,因此称为依赖注入,也称为控制反转。
  
   配置依赖
     根据注入方式的不同,bean的依赖注入通常表现为如下两种形式:
        1,属性:通过property属性来指定对应的设值注入。
        2,构造器参数:通过constructor-arg属性来指定对应的构造注入。
   在Spring在实例化BeanFactory时,通常会校验BeanFactory中的每一个Bean的配置。这些校验包括:
        1.bean引用的合作者指向一个合法的bean.
        2.对于被设置为pre-instantiated的bean的singleton行为,Spring会在创建BeanFactory时,同时实例化bean.实例化bean时,也会将它所依赖的bean一起实例化。
        此外,BeanFactory与ApplicationContext实例化容器中的bean的时机不同:前者在程序需要bean实例时才创建Bean;而后者在加载ApplicationContext实例时,会自动实例化容器中的全部bean.
        ApplicationContext是默认预实例化singleton bean。ApplicationContext实例化过程比BeanFactory时间和内存占用率大,但可以在ApplicationContext创建时就检验出配置错误。当然可以通过lazy-load属性为“true”来改变ApplicationContext的默认行为!
        bean的依赖通常可以接受如下元素指定值:
            1.value.
            2.ref.
            3.bean.
            4.list.set.map.以及props.

    首先来看看value元素。
        value元素用于确定字符串参数。XML文档解析器解析以String解析出这些数据,然后将这些参数由PropertyEditors完成转换(从java.lang.String类型转换为所需的参数类型)。
        for example:
-------------------------------------------------------------------------------------------

package org.viking.spring.itf;

public interface ValueElementItf
{
 public void shows();
}

-------------------------------------------------------------------------------------------

package org.viking.spring.imp;

import org.viking.spring.itf.ValueElementItf;

public class ValueElement implements ValueElementItf {

 private int integerProperty;
 
 private double doubleProperty;
 
 private String email;
 
 public void shows()
 {
  System.out.println(integerProperty);
  System.out.println(doubleProperty);
  System.out.println(email);
 }

 public void setIntegerProperty(int integerProperty) {
  this.integerProperty = integerProperty;
 }

 public void setDoubleProperty(double doubleProperty) {
  this.doubleProperty = doubleProperty;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 

}

-------------------------------------------------------------------------------------------
<?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.0.xsd">
 
 <bean id="value" class="org.viking.spring.imp.ValueElement">
  <property name="integerProperty">
   <value>1</value>
  </property>
  <property name="doubleProperty">
   <value>2.3</value>
  </property>
 </bean>
</beans>
-------------------------------------------------------------------------------------------
 

package org.viking.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.viking.spring.itf.Person;
import org.viking.spring.itf.ValueElementItf;

import junit.framework.TestCase;

public class TestElement extends TestCase
{
 public void testValueElement()
 {
  ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  ValueElementItf value = (ValueElementItf)app.getBean("value");
  value.shows();
 }

}
-------------------------------------------------------------------------------------------
   value元素的值可以通过<null/>元素指定为空。
    把上面的applicationContext.xml文件代码改一下。
-------------------------------------------------------------------------------------------
<?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.0.xsd">
 
 <bean id="value" class="org.viking.spring.imp.ValueElement">
  <property name="integerProperty">
   <value>1</value>
  </property>
  <property name="doubleProperty">
   <value>2.3</value>
  </property>
  <property name="email">
   <value></value>
  </property>
 </bean>
</beans>
-------------------------------------------------------------------------------------------
改过之后的测试打印出了Null.

        接着是ref元素
            如果需要为bean注入的属性是容器中的某个bean实例,推荐使用ref。
             ref元素通常有两个属性:
                1.bean
                2.local
            bean用于指定在不同一个xml配置文件中的bean,而local用于指定同一个xml配置文件中的其他bean,并且local属性值只能是其他bean的id属性,让Spring在解析XML时,验证bean的名称。

        bean元素
            如果某个bean的依赖bean不想被Spring容器直接访问,则可以使用嵌套bean。
            嵌套bean只对嵌套它的外部bean有效,而Spring容器无法直接访问嵌套bean,因此嵌套bean无需id属性。
            嵌套bean的配置形式,保证嵌套bean不能被容器访问,提高了程序的内聚性。
            嵌套bean的例子会在下一个元素讲解中使用到!
        list,set,map,以及props元素
            list,set,map和props元素分别用来设置类型为List,Set,Map和Properties的属性值,用来为bean注入集合值。
            for example:
-------------------------------------------------------------------------------------------

package org.viking.spring.itf;

public interface Person
{
 public void shows();
}
-------------------------------------------------------------------------------------------

package org.viking.spring.imp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.viking.spring.itf.Person;

public class Chinese implements Person
{

 private List  schools = new ArrayList();
 
 private Map score = new HashMap();
 
 private Properties  health = new Properties();
 
 private Set axes = new HashSet();
 
 public void shows()
 {
  System.out.println(schools);
  System.out.println(score);
  System.out.println(health);
  System.out.println(axes);
 }

 public void setSchools(List schools) {
  this.schools = schools;
 }

 public void setScore(Map score) {
  this.score = score;
 }

 public void setHealth(Properties health) {
  this.health = health;
 }

 public void setAxes(Set axes) {
  this.axes = axes;
 }

}
-------------------------------------------------------------------------------------------
package org.viking.spring.imp;
public class ValueElement
{
    public ValueElement()
    {
        System.out.println("嵌套bean的测试!");
    }
}
-------------------------------------------------------------------------------------------

<?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.0.xsd">

<bean id="chinese" class="org.viking.spring.imp.Chinese">
  <property name="schools">
   <list>
    <value>小学</value>
    <value>中学</value>
    <value>大学</value>
   </list>
  </property>
  <property name="score">
   <map>
    <entry key="数学">
     <value>87</value>
    </entry>
     <entry key="英语">
     <value>89</value>
    </entry>
     <entry key="语文">
     <value>82</value>
    </entry>
   </map>
  </property>
  <property name="health">
   <props>
    <prop key="血压">正常</prop>
    <prop key="身高">175</prop>
   </props>
  </property>
  <property name="axes">
   <set>
    <value>字符串斧子</value>
    <ref local="value"/>
    <bean class="org.viking.spring.imp.ValueElement"></bean>
    <!--这就是嵌套bean-->
   </set>
  </property>
 </bean>

</beans>

-------------------------------------------------------------------------------------------

package org.viking.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.viking.spring.itf.Person;
import org.viking.spring.itf.ValueElementItf;

import junit.framework.TestCase;

public class TestElement extends TestCase
{

public void testCollection()
 {
  ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
  Person p1 =  (Person)app.getBean("chinese");
  p1.shows();
 }
}
-------------------------------------------------------------------------------------------
    map元素entry的值以及set元素的值都可以使用如下元素:
        1.vlaue:确定基本数据类型值或字符串类型值。
        2.ref:确定另外一个bean为属性值。
        3.bean:确定一个嵌套bean为属性值。
        4.list,set,map,以及props:确定集合值为属性值。
    这么说可能有点抽象,大家运行一下以上代码,就一清二楚了!

    在实际应用中,某个实例的属性可能是某个方法的返回值,类的field值,或者属性值。这种非常规的方法Spring同样支持!Spring甚至支持将bean实例的属性值,方法返回值及field值直接赋给一个变量。
       好了,今天就到这,明天接着写注入属性值!

-------以上的文字以及代码摘录于李刚写的《轻量级J2EE开发企业应用实战》,代码有少许变动!

Identify the aspects of your application that vary and separate them from what stays the same.