Spring IOC

来源:互联网 发布:迟瑞与知夏圆房视频 编辑:程序博客网 时间:2024/06/14 06:24
        Spring IOC是Spring最重要也是最基础的两个特性之一(别一个是AOP,现不在讨论)。Spring框架的实现控制反转(IoC)的原则,也被称为依赖注入(DI)。过程对象定义它们的依赖关系,也就是说,他们使用的其它对象,只能通过构造函数参数,参数工厂方法或对象实例上设置的属性构造或从工厂回来后的方法。然后容器注入这些依赖项时创建bean。这个过程从根本上是反,因此得名“控制反转(IoC),控制实例化bean本身或者它的位置依赖关系通过使用直接建设类,或者一个Service Locator模式等机制。

1、Spring IOC(DI)

分为set注入、构造器注入与静态工厂方法注入用得最多的还是set注入与构造器注入。

1.1 Set注入

<bean id="exampleBean" class="examples.ExampleBean"><!-- setter injection using the nested <ref/> element --><property name="beanOne"><ref bean="anotherExampleBean"/></property><!-- setter injection using the neater 'ref' attribute --><property name="beanTwo" ref="yetAnotherBean"/><property name="integerProperty" value="1"/></bean><bean id="anotherExampleBean" class="examples.AnotherBean"/><bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
对应的Java类为:
public class ExampleBean {  private AnotherBean beanOne;  private YetAnotherBean beanTwo;  private int i;  public void setBeanOne(AnotherBean beanOne) {      this.beanOne = beanOne;  }  public void setBeanTwo(YetAnotherBean beanTwo) {      this.beanTwo = beanTwo;  }  public void setIntegerProperty(int i) {      this.i = i;  }}

1.2 构造器注入

Spring还有一种DI方式是使用构造器注入值.

<bean id="exampleBean" class="examples.ExampleBean"><!-- constructor injection using the nested <ref/> element --><constructor-arg>  <ref bean="anotherExampleBean"/></constructor-arg><!-- constructor injection using the neater 'ref' attribute --><constructor-arg ref="yetAnotherBean"/><constructor-arg type="int" value="1"/></bean><bean id="anotherExampleBean" class="examples.AnotherBean"/><bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
对应的Java实体类为:
public class ExampleBean {  private AnotherBean beanOne;  private YetAnotherBean beanTwo;  private int i;  public ExampleBean(      AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {      this.beanOne = anotherBean;      this.beanTwo = yetAnotherBean;      this.i = i;  }}
构造器中的参数对应实体类 ExamleBean 中的构造器中的参数。

1.3  静态工厂方法

现在考虑一下下面的例子。Spring同样也可以用一个静态工厂方法取代构造器注入来返回对象的实例.
<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance"><constructor-arg ref="anotherExampleBean"/><constructor-arg ref="yetAnotherBean"/><constructor-arg value="1"/></bean><bean id="anotherExampleBean" class="examples.AnotherBean"/><bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
上面的代码对应的Java类为:

public class ExampleBean {  // a private constructor  private ExampleBean(...) {    ...  }    // a static factory method; the arguments to this method can be  // considered the dependencies of the bean that is returned,  // regardless of how those arguments are actually used.  public static ExampleBean createInstance (          AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {      ExampleBean eb = new ExampleBean (...);      // some other operations...      return eb;  }}

2、p-namespace -- 更加简洁的set注入

我们的开发中一定要涉及到数据库的开发。一般我们配置数据库使用下面的方法:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><!-- results in a setDriverClassName(String) call --><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mydb"/><property name="username" value="root"/><property name="password" value="masterkaoli"/></bean>
如果我们在Spring的XML配置文件中引用p-namespace命名空间。我们就可以这样配置上面的文件
<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:p="http://www.springframework.org/schema/p"     xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"      destroy-method="close"      p:driverClassName="com.mysql.jdbc.Driver"      p:url="jdbc:mysql://localhost:3306/mydb"      p:username="root"      p:password="masterkaoli"/></beans>
是不是更加简洁了?

3、c-namespaces -- 更加简洁的构造器注入

与p-namespaces一样我们同样需要引入c-namespaces命名空间。
<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:c="http://www.springframework.org/schema/c"  xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans.xsd">  <bean id="bar" class="x.y.Bar"/>  <bean id="baz" class="x.y.Baz"/>  <-- 'traditional' declaration -->  <bean id="foo" class="x.y.Foo">      <constructor-arg ref="bar"/>      <constructor-arg ref="baz"/>      <constructor-arg value="foo@bar.com"/>  </bean>  <-- 'c-namespace' declaration -->  <bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="foo@bar.com"></beans>

4、idref -- 检测ID bean是否存在

这个 idref 元素只是一简单的检测一下配置为这个当前bean在<constructor-arg/>或者<property/>标签中使用别一个ID的bean文件在Spring容器标签中是否存在。
<bean id="theTargetBean" class="..."/><bean id="theClientBean" class="...">  <property name="targetName"><!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown -->        <idref bean="theTargetBean" />  </property></bean>
等同于下面的配置
<bean id="theTargetBean" class="..." /><bean id="client" class="...">  <property name="targetName" ref="theTargetBean" /></bean>

5、inner beans

一个bean元素包含在<constructor-arg/>或者<property/>之中的配置被称为inner bean也就是Java中的内部类。
<bean id="outer" class="..."><!-- instead of using a reference to a target bean, simply define the target bean inline --><property name="target">  <bean class="com.example.Person"> <!-- this is the inner bean -->    <property name="name" value="Fiona Apple"/>    <property name="age" value="25"/>  </bean></property></bean>

6、Collection

你可以使用Spring中的<list/>, <set/>, <map/>和<props/>标签,用来设置Java中Collection类型,分别对应的是List,Set,Map和Properties。

<bean id="moreComplexObject" class="example.ComplexObject"><!-- results in a setAdminEmails(java.util.Properties) call --><property name="adminEmails">  <props>  <prop key="administrator">administrator@example.org</prop>  <prop key="support">support@example.org</prop>  <prop key="development">development@example.org</prop>  </props></property><!-- results in a setSomeList(java.util.List) call --><property name="someList">  <list>  <value>a list element followed by a reference</value>  <ref bean="myDataSource" />  </list></property><!-- results in a setSomeMap(java.util.Map) call --><property name="someMap">  <map>  <entry key="an entry" value="just some string"/>  <entry key ="a ref" value-ref="myDataSource"/>  </map></property><!-- results in a setSomeSet(java.util.Set) call --><property name="someSet">  <set>  <value>just some string</value>  <ref bean="myDataSource" />  </set></property></bean>
对于Map的key或者value,set的值同样也可以使用下面的标签。

bean | ref | idref | list | set | map | props | value | null
同样对于Collection,Spring也支付Collection包含Collection。但是对于<list/>, <map/>, <set/>或者<props/>这些集合类型,Spring只支付配置它们本身。就是<list/>的子标签只能是</list>.<props>子标签只能包含<props/>.

<beans><bean id="parent" abstract="true" class="example.ComplexObject">  <property name="adminEmails">      <props>          <prop key="administrator">administrator@example.com</prop>          <prop key="support">support@example.com</prop>      </props>  </property></bean><bean id="child" parent="parent">  <property name="adminEmails">      <!-- the merge is specified on the *child* collection definition -->      <props merge="true">          <prop key="sales">sales@example.com</prop>          <prop key="support">support@example.co.uk</prop>      </props>  </property></bean><beans>

7、null值或者空String

Spring对待空参数就像空字符串一样。下面的基于xml的配置元数据片段将email属性设置为空字符串值(" ")

<bean class="ExampleBean"><property name="email" value=""/></bean>
上在的例子同样等价于Java中的 exampleBean.setEmail("");<null />标签代表null值,例如:
<bean class="ExampleBean"><property name="email"><null/><property/></bean>
上在的例子同样等价于Java中的 exampleBean.setEmail(null);







0 0
原创粉丝点击