posts - 120,  comments - 10,  trackbacks - 0
  2006年3月23日
Spring学习笔记(一)依赖注入
 
依赖注入——是Spring最灵魂的设计思想,有人也叫做控制反转。
1、不管是依赖注入(DI:Dependency Injection)还是控制反转(IoC:Inversion of Control)它的思想是:控制权由应用代码中转到了外部
容器,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
2、依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,带来灵活性。
3、举个例子来说明这个问题。
我曾看到夏昕的《Spring 开发指南》,上面为说明这个思想,举了电脑、USB硬盘和U盘的例子,感觉还是不太贴切,今天想了个自认为比较好
理解的例子:
有两种变形金刚的玩具,
一种是固定的,我把它比作原来那种控制权由应用代码写死的程序
一种可以拆开重新装配的,我把它比作用了依赖注入设计思想的程序
变形金刚的各个部件就象程序的各个组件。
变形金刚的厂家,相对它来说是内部的。就象程序的代码
变形金刚的玩家,相对它来说是外部的。就象程序的容器
大家试想一下,固定变形金刚的控制权是不是厂家决定的,外部无能为力
而可拆卸的变形金刚的控制权转移到了外部的玩家,玩家在玩之前可以重新决定各个组件的连接关系
而这种组件的连接图是不是也很像依赖注入思想里的配置文件。
大家再从这个例子分析一下依赖注入的目标。
1)功能变化有限,你变形金刚设计的再好,可变换的东西也不过相似的几种。
2)真正的目的是提升组件重用的概率,带来灵活性。
引用地址 http://spaces.msn.com/pococoon/blog/cns!D25B6032F7AD1992!195.entry
posted @ 2006-03-23 13:46 阿成 阅读(114) | 评论 (0)编辑 收藏
Spring使用BeanFactory模式来管理Bean,但Spring中提到的Bean不是标准的意义上的JavaBean(仅包含一个默认的构造函数,在属性后面定义相对应的setter和getter方法),而是任何你想让它管理的类,比如连接池、甚至BeanFactory本身。

一)Bean的设计常用下面几种模式

1、标准Bean:

使用默认的构造函数和基于setter、getter方法的依赖注射

Bean类代码:

java代码: 

public class ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
   
    publicvoid setBeanOne(BeanOne beanOne){
        this.beanOne = beanOne;
    }
   
    publicvoid setBeanTwo(BeanTwo beanTwo){
        this.beanTwo = beanTwo;
    }
   
    publicvoid setCount(int count){
        this.count = count;
    }   
}


在配置文件中定义:

java代码: 

<bean id="exampleBean" class="examples.ExampleBean">
    <property name="beanOne"><ref bean="bean1"/></property>
    <property name="beanTwo"><ref bean="bean2"/></property>
    <property name="count"><value>1</value></property>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


2、构造函数模式

自定义的构造函数,基于构造函数参数的依赖注射

Bean类代码:

java代码: 

public class ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
   
    public ExampleBean(BeanOne beanOne, BeanTwo beanTwo, int count){
        this.beanOne = beanOne;
        this.beanTwo = beanTwo;
        this.count = count;
    }
}


在配置文件中定义:
java代码: 


<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


3、静态工厂方法模式

静态工厂方法必须是static的,基于方法参数的依赖注射。

Bean类代码:

java代码: 

public class ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
    //构造函数私有
    private ExampleBean(BeanOne beanOne, BeanTwo beanTwo, int count){
        this.beanOne = beanOne;
        this.beanTwo = beanTwo;
        this.count = count;
    }
    //对外提供静态的方法
    publicstatic ExampleBean createInstance(BeanOne beanOne, BeanTwo beanTwo, int count){
        ExampleBean eb = new ExampleBean(beanOne,beanTwo,count);
        return eb;
    }
}


在配置文件中定义:

java代码: 

<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>



3、实例工厂方法模式

调用一个已存在的bean(这个bean应该是工厂类型)的工厂方法来创建新的bean,基于方法参数的依赖注射

该模式没有Bean类;

在配置文件中定义:

java代码: 

<bean id="exampleBean"
      factory-bean="myFactoryBean"
      factory-method="createInstance"/>

<bean id="myFactoryBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


二)Bean其它参数的配置

一个常用Bean的配置参数和解释

<bean id="" ——标志符,用它引用唯一的Bean
class="" ——该Bean对应的类,前面说到实例工厂方法模式创建的Bean没有类
singleton="" ——值为true或false,标识该Bean是否为单实例模式?如果为false则对这个bean
的每次请求都会创建一个新的bean实例
init-method="" ——向应用层返回引用前执行的初始化方法
destroy-method="" ——该Bean的销毁方法
depends-on=""> ——在Bean加载前,首先加载的指定资源
....
</bean>

三)property(或constructor-arg元素)的配置

1、用字符串形式指定常见类型的属性或参数的value值,JavaBean的PropertyEditor负责类型转化如:

java代码: 

<property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
    <value>jdbc:mysql://localhost:3306/mydb</value>
</property>


2、注意null和""(空串)的区别,如:
java代码: 


<property name="email"><value></value></property>
<property name="email"><null/></property>



3、list、set、map、以及 props 元素用来定义和设置Java对应类型List、Set、Map、和 Properties ,如:

java代码: 


<property name="school">
   <props>
      <prop key="school01">The xi'an technology university</prop>
      <prop key="school02">The BeiJing university</prop>
   </props>
</property>

<property name="someList">
   <list>
      <value>a list element followed by a reference</value>
      <ref bean="myDataSource"/>
   </list>
</property>

<property name="someMap">
   <map>
      <entry key="001">
         <value>just some string</value>
      </entry>
      <entry key="yup a ref">
         <ref bean="myDataSource"/>
      </entry>
   </map>
</property>
       
<property name="someSet">
      <set>
         <value>just some string</value>
         <ref bean="myDataSource"/>
      </set>
</property>


4、内部Bean和ref元素引用容器管理的其他bean

一个内部Bean的例子:
java代码: 


<bean id="dep" class="com.bean.Conpany">
    <property name="manager">
        <bean class="com.bean.Person">
            <property name="name"><value>Tony</value></property>
            <property name="age"><value>51</value></property>
        </bean>
    </property>
</bean>


ref元素引用的例子:
java代码: 


<bean id="person_manger" class="com.bean.Person">
    <property name="name"><value>Tony</value></property>
    <property name="age"><value>51</value></property>
</bean>

<bean id="dep" class="com.bean.Conpany">
    <property name="manager">
        <idref bean="person_manager"/>
    </property>
</bean>



注:元素引用可以是下面三种权限:
1)<idref bean="person_manager"/>
引用的Bean可以在同一个BeanFactory/ApplicationContext(无论是否在同一个XML文件中)中,也可以在父BeanFactory/ApplicationContext中
2)<idref local="person_manager"/>
引用的bean在同一个XML文件中
3)<idref parent="person_manager"/>
引用的bean必须在当前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中.
有新文章时间: 2006-3-23 12:58:26    标题: Spring学习笔记(二)Bean引用回复将这个帖子加入我的Blog

Spring使用BeanFactory模式来管理Bean,但Spring中提到的Bean不是标准的意义上的JavaBean(仅包含一个默认的构造函数,在属性后面定义相对应的setter和getter方法),而是任何你想让它管理的类,比如连接池、甚至BeanFactory本身。

一)Bean的设计常用下面几种模式

1、标准Bean:

使用默认的构造函数和基于setter、getter方法的依赖注射

Bean类代码:

java代码: 

publicclass ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
   
    publicvoid setBeanOne(BeanOne beanOne){
        this.beanOne = beanOne;
    }
   
    publicvoid setBeanTwo(BeanTwo beanTwo){
        this.beanTwo = beanTwo;
    }
   
    publicvoid setCount(int count){
        this.count = count;
    }   
}


在配置文件中定义:

java代码: 

<bean id="exampleBean" class="examples.ExampleBean">
    <property name="beanOne"><ref bean="bean1"/></property>
    <property name="beanTwo"><ref bean="bean2"/></property>
    <property name="count"><value>1</value></property>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


2、构造函数模式

自定义的构造函数,基于构造函数参数的依赖注射

Bean类代码:

java代码: 

publicclass ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
   
    public ExampleBean(BeanOne beanOne, BeanTwo beanTwo, int count){
        this.beanOne = beanOne;
        this.beanTwo = beanTwo;
        this.count = count;
    }
}


在配置文件中定义:
java代码: 


<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


3、静态工厂方法模式

静态工厂方法必须是static的,基于方法参数的依赖注射。

Bean类代码:

java代码: 

publicclass ExampleBean {
    private BeanOne beanOne;
    private BeanTwo beanTwo;
    privateint count;
    //构造函数私有
    private ExampleBean(BeanOne beanOne, BeanTwo beanTwo, int count){
        this.beanOne = beanOne;
        this.beanTwo = beanTwo;
        this.count = count;
    }
    //对外提供静态的方法
    publicstatic ExampleBean createInstance(BeanOne beanOne, BeanTwo beanTwo, int count){
        ExampleBean eb = new ExampleBean(beanOne,beanTwo,count);
        return eb;
    }
}


在配置文件中定义:

java代码: 

<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>



3、实例工厂方法模式

调用一个已存在的bean(这个bean应该是工厂类型)的工厂方法来创建新的bean,基于方法参数的依赖注射

该模式没有Bean类;

在配置文件中定义:

java代码: 

<bean id="exampleBean"
      factory-bean="myFactoryBean"
      factory-method="createInstance"/>

<bean id="myFactoryBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg><ref bean="bean1"/></constructor-arg>
    <constructor-arg><ref bean="bean2"/></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
</bean>

<bean id="bean1" class="examples.BeanOne"/>
<bean id="bean2" class="examples.BeanTwo"/>


二)Bean其它参数的配置

一个常用Bean的配置参数和解释

<bean id="" ——标志符,用它引用唯一的Bean
class="" ——该Bean对应的类,前面说到实例工厂方法模式创建的Bean没有类
singleton="" ——值为true或false,标识该Bean是否为单实例模式?如果为false则对这个bean
的每次请求都会创建一个新的bean实例
init-method="" ——向应用层返回引用前执行的初始化方法
destroy-method="" ——该Bean的销毁方法
depends-on=""> ——在Bean加载前,首先加载的指定资源
....
</bean>

三)property(或constructor-arg元素)的配置

1、用字符串形式指定常见类型的属性或参数的value值,JavaBean的PropertyEditor负责类型转化如:

java代码: 

<property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
    <value>jdbc:mysql://localhost:3306/mydb</value>
</property>


2、注意null和""(空串)的区别,如:
java代码: 


<property name="email"><value></value></property>
<property name="email"><null/></property>



3、list、set、map、以及 props 元素用来定义和设置Java对应类型List、Set、Map、和 Properties ,如:

java代码: 


<property name="school">
   <props>
      <prop key="school01">The xi'an technology university</prop>
      <prop key="school02">The BeiJing university</prop>
   </props>
</property>

<property name="someList">
   <list>
      <value>a list element followed by a reference</value>
      <ref bean="myDataSource"/>
   </list>
</property>

<property name="someMap">
   <map>
      <entry key="001">
         <value>just some string</value>
      </entry>
      <entry key="yup a ref">
         <ref bean="myDataSource"/>
      </entry>
   </map>
</property>
       
<property name="someSet">
      <set>
         <value>just some string</value>
         <ref bean="myDataSource"/>
      </set>
</property>


4、内部Bean和ref元素引用容器管理的其他bean

一个内部Bean的例子:
java代码: 


<bean id="dep" class="com.bean.Conpany">
    <property name="manager">
        <bean class="com.bean.Person">
            <property name="name"><value>Tony</value></property>
            <property name="age"><value>51</value></property>
        </bean>
    </property>
</bean>


ref元素引用的例子:
java代码: 


<bean id="person_manger" class="com.bean.Person">
    <property name="name"><value>Tony</value></property>
    <property name="age"><value>51</value></property>
</bean>

<bean id="dep" class="com.bean.Conpany">
    <property name="manager">
        <idref bean="person_manager"/>
    </property>
</bean>



注:元素引用可以是下面三种权限:
1)<idref bean="person_manager"/>
引用的Bean可以在同一个BeanFactory/ApplicationContext(无论是否在同一个XML文件中)中,也可以在父BeanFactory/ApplicationContext中
2)<idref local="person_manager"/>
引用的bean在同一个XML文件中
3)<idref parent="person_manager"/>
引用的bean必须在当前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中

引用注明出处:http://spaces.msn.com/pococoon/blog/cns!D25B6032F7AD1992!193.entry


posted @ 2006-03-23 13:42 阿成 阅读(100) | 评论 (0)编辑 收藏