IOC之bean之间的关系讲解

  本文主要讲了Spring中Bean之间的关系,分为继承、依赖和引用三个类型。文章中都分别有例子和用法分析。

一、继承Bean配置

  • Spring允许继承bean的配置 ,被继承的bean称为父bean,继承这个父Bean的Bean称为子Bean
  • 子Bean从父Bean中继承配置,包括Bean的属性配置
  • 子Bean也可以 覆盖 从父Bean继承过来的配置
  • 父Bean可以作为配置模版,也可以作为Bean实例, 若只想把父Bean作为模版,可以配置<bean>的abstract属性为true ,这样Spring将不会实例化这个Bean
  • 并不是<bean>元素里的所有属性都会被继承 。比如:autowire,abstract等。 
  • 也 可以忽略父Bean的class属性 ,让子Bean指定自己的类,而共享相同的属性配置,但此时 abstract必须设为true

使用案例:

定义House.java:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mucfc;  
  2.   
  3. public class House {  
  4.     private String houseSize;  
  5.     private String housePosition;  
  6.     private String housePrice;  
  7.     public String getHouseSize() {  
  8.         return houseSize;  
  9.     }  
  10.     public void setHouseSize(String houseSize) {  
  11.         this.houseSize = houseSize;  
  12.     }  
  13.     public String getHousePosition() {  
  14.         return housePosition;  
  15.     }  
  16.     public void setHousePosition(String housePosition) {  
  17.         this.housePosition = housePosition;  
  18.     }  
  19.     public String getHousePrice() {  
  20.         return housePrice;  
  21.     }  
  22.     public void setHousePrice(String housePrice) {  
  23.         this.housePrice = housePrice;  
  24.     }  
  25.     public String toString(){  
  26.         return "房子大小:"+houseSize+" 房子位置:"+housePosition+" 房子价格:"+housePrice;  
  27.     }  
  28. }  

如果多个bean存在相同的配置信息,Spring允许我们定义一个父,子将自动继承父的配置信息。

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <!-- 定义抽象bean -->  
  2. <bean id="abstracthouse" class="com.mucfc.House" p:houseSize="150坪"  
  3.    p:housePosition="科苑花园" p:housePrice="15万"/>  
  4. <!-- 继承于abstracthouse -->  
  5.  <bean id="house2" parent="abstracthouse" p:housePosition="汇景苑"/>  
  6.  <!-- 继承于abstracthouse -->  
  7.  <bean id="house3" parent="abstracthouse" p:housePrice="8万"/>  
使用:  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. House house5=applicationContext.getBean("house2",House.class);  
  2. House house6=applicationContext.getBean("house3",House.class);  
  3. System.out.println(house5);  
  4. System.out.println(house6);  
输出结果:

房子大小:150坪 房子位置:汇景苑 房子价格:15万
房子大小:150坪 房子位置:科苑花园 房子价格:8万

      

         house1跟house2都继承自abstracthouse,Spring会将父bean的配置信息传递给子bean,如果子bean提供了父bean已有的配置信息,那么子bean的会覆盖父bean的.

        父bean的功能主要是为了简化子bean的配置,所以一般声明为abstract=“true”,表示这个不实例化为一个对应的Bean,如果用户不指定该属性为true,那么IOC容器会实例化一个名叫abstractcar的Bean。


二、依赖Bean配置

  • Spring允许用户通过depends-on属性设定Bean前置依赖的Bean ,前置依赖的Bean会在本Bean实例化之前创建好
  • 如果前置依赖于多个Bean,则可以通过逗号,空格或的方式配置Bean的名称
depends-on:

depends-on属性可以用于当前bean初始化之前显式地强制一个或多个bean被初始化。下面的例子中使用了depends-on属性来指定一个bean的依赖。

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id="buyHouser" class="com.mucfc.depend.BuyHouser" />   
  2. <bean id="HouseAgent" class="com.mucfc.depend.HouseAgent" depends-on="buyHouser" />   

若需要表达对多个bean的依赖,可以在'depends-on'中将指定的多个bean名字用分隔符进行分隔,分隔符可以是逗号、空格及分号等。下面的

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id="HouseAgent" class="com.mucfc.depend.HouseAgent" init-method="initHouseAgent" depends-on="buyHouser,sellHouser" />   
例子中使用了'depends-on'来表达对多个bean的依赖。

延迟初始化bean;

在XML配置文件中,延迟初始化将通过<bean/>元素中的lazy-init属性来进行控制。例如:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id="buyHouser" class="com.mucfc.depend.BuyHouser" lazy-init="true"/>   
  2. <bean id="sellHouser" class="com.mucfc.depend.SellHouser" />   
当ApplicationContext实现加载上述配置时,设置为lazy的bean-buyHouser将不会在ApplicationContext启动时提前被实例化,而not.lazy--sellHouser却会被提前实例化。

       需要说明的是,如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化singleton bean时,它必须也确保所有上述singleton 依赖bean也被预先初始化,当然也包括设置为延迟实例化的bean。因此,如果Ioc容器在启动的时候创建了那些设置为延迟实例化的bean的实例,你也不要觉得奇怪,因为那些延迟初始化的bean可能在配置的某个地方被注入到了一个非延迟初始化singleton bean里面。


使用范例:
1.买房人BuyHouser.java
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mucfc.depend;  
  2.   
  3. public class BuyHouser {  
  4. private String name;  
  5.   
  6. public String getName() {  
  7.     return name;  
  8. }  
  9.   
  10. public void setName(String name) {  
  11.     this.name = name;  
  12. }  
  13. public void initBuyHouser(){  
  14.     System.out.println("初始化了BuyHouser");  
  15.     }  
  16. }  
2、卖房人SellHouser.java
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mucfc.depend;  
  2.   
  3. public class SellHouser {  
  4.     private String name;  
  5.     public String getName() {  
  6.         return name;  
  7.     }  
  8.   
  9.     public void setName(String name) {  
  10.         this.name = name;  
  11.     }  
  12.     public void initSellHouser (){  
  13.         System.out.println("初始化了SellHouser ");  
  14.         }  
  15. }  
3、房屋中介HouseAgent.java
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mucfc.depend;  
  2.   
  3. public class HouseAgent {  
  4. private BuyHouser buyHouser;  
  5. private SellHouser sellHouser;  
  6. public BuyHouser getBuyHouser() {  
  7.     return buyHouser;  
  8. }  
  9. public void setBuyHouser(BuyHouser buyHouser) {  
  10.     this.buyHouser = buyHouser;  
  11. }  
  12. public SellHouser getSellHouser() {  
  13.     return sellHouser;  
  14. }  
  15. public void setSellHouser(SellHouser sellHouser) {  
  16.     this.sellHouser = sellHouser;  
  17. }  
  18. public void initHouseAgent(){  
  19.     System.out.println("初始化了HouseAgent");  
  20.     }  
  21. }  
4、beans.xml
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans    
  6.                 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
  7.         http://www.springframework.org/schema/context    
  8.         http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  9.   
  10.   
  11.     <bean id="houseAgent" class="com.mucfc.depend.HouseAgent" init-method="initHouseAgent" depends-on="buyHouser,sellHouser" />   
  12.     <bean id="buyHouser" class="com.mucfc.depend.BuyHouser" init-method="initBuyHouser" lazy-init="true"/>   
  13.     <bean id="sellHouser" class="com.mucfc.depend.SellHouser" init-method="initSellHouser" lazy-init="true"/>   
  14.   
  15. </beans>  
5、测试

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.mucfc.depend;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class Test {  
  7.   
  8.     public static void main(String[] args) {  
  9.          ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");  
  10.       
  11.     }  
  12.   
  13. }  
结果:


注意,这里我将BuyHouser和SellHouser都设置成lazy-init="true",但是由于房屋中介HouseAgent依赖到它们两个,所以你你加载这个beans.xml文件时,还是会先把BuyHouser和SellHouser实例化。

三、引用Bean配置

代码结构:
可写成
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id="houseAgent1" class="com.mucfc.depend.HouseAgent" p:buyHouser="buyHouser" p:sellHouser="sellHouser"/>  
  2.    <bean id="houseAgent2" class="com.mucfc.depend.HouseAgent" p:buyHouser-ref="buyHouser" p:sellHouser-ref="sellHouser"/>  
或写成
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id = "houseAgent3" class = "com.mucfc.depend.HouseAgent" >  
  2.       <property name="buyHouser">  
  3.           <ref bean="buyHouser"/>  
  4.       </property>  
  5.       <property name="sellHouser">  
  6.           <ref local="sellHouser"/>  
  7.       </property>  
  8.   </bean>   
<ref local="xx"/> 
        用"local"属性指定目标其实是指向同一文件内对应"id"属性值为此"local"值的索引"local"属性的值必须和目标bean的id属性相同。如果同一文件内没有匹配的元素,xml解析器将提示错误。同样,如果目标在同一XML文件内,使用"local"变量是最好的选择(为了尽可能早地知道错误)
<ref bean="xx"/> 
        用"bean"属性指定目标bean是最常规的形式,这允许创建索引到任何同一个容器内的bean(无论是否在同一XML文件中)或者父级的容器内的bean。"bean"属性的值可以和目标bean的"id"属性相同,也可以和目标bean的"name"属性内的一个值相同

1 、用 local 属性指定目标 bean 可以利用 xml 解析器的能力在同一个 XML配置文件中验证 xml id 引用,没有匹配的元素,xml 解析器就会产生一个 error, 所以如果引用的 bean 在同一个 XML配置 文件中 , 那么用 local 形式是最好的选择 .
2 、可以这么说,<ref bean> 是寻找所有 XML配置文件中的 bean; <ref local> 是寻找本 xml 文件中的 bean.
3 、<ref> 提供了如下几方面的属性 :
1)bean: 在当前 Spring XML 配置文件中,或者在同一 BeanFactory(ApplicationContext) 中的其他 JavaBean 中寻找引入的BEAN.
2)local: 仅在当前 Spring XML 配置文件中寻找引入的BEAN.
如果借助于 Spring IDE, 则在编译期可以对其依赖的 JavaBean 进行验证。基于 local 方式,开发者能够使用到 XML 本身提供的优势,而进行验证。 3)parent: 用于指定其依赖的父 JavaBean 定义。


        林炳文Evankaka原创作品。转载请注明出处 http://blog.csdn.net/evankaka
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值