Spring IOC

        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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值