博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Spring Core

Posted on 2011-02-14 22:19  commond  阅读(1258)  评论(0编辑  收藏  举报

wps_clip_image-30816

名词解释:

Bean: Bean就是由Spring容器初始化,装配及被管理的对象,实际上Bean就是对象。

BeanFactory: BeanFactory是访问Spring beans的一个容器。所有的Spring Beans的定义都会在这里被统一的处理。换句话说,BeanFactory interface是一个应用组件(Spring Bean)的集中注册器和配置器。从一般意义上来讲,BeanFactory是用来加载和管理Spring Bean definition的。但是同时BeanFactory对Spring Bean definition存于何处则不关心。

观察其定义:

public interface BeanFactory {

Object getBean(String name) throws BeansException;

Object getBean(String name, Class requiredType) throws BeansException;

boolean containsBean(String name);

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

Class getType(String name) throws NoSuchBeanDefinitionException;

String[] getAliases(String name) throws NoSuchBeanDefinitionException;

}

BeanFactory管理的两类对象:sington&prototype

Sington

wps_clip_image-5402

Prototype

wps_clip_image-3565开场白:Spring FrameWork的核心是控制反转容器(IoC),而BeanFactory则是控制反转容器的核心接口。

那么,什么是控制反转呢:

首先。我们需要了解什么是对象依赖。

如果你想认识一个女孩,你会怎么做呢

假设有如下代码:

public class Boy { 
      void Find Girl (){
          Girlkity= new Girl ();
       }
}

是的,我们完全可以自己找,但是我们或许不能首先提出分手了,因为毕竟是自己主动的,或许这个比喻不很确切,但是肯定的一点是,如果你想把女友从kity更换成jess的话,你必须自己去说服kity分手,再去追求jess。这太麻烦了。(即如果Girl对象发生改变时,我们可能不得不去更改对象Boy的代码)

或许我们可以找朋友来帮我们介绍吧

public class Boy { 
      void Find Girl (){
          Girlgirl = GirlFactory.createGirl ();
      }
}

真是好方法,但是这样介绍总觉得有点不对劲,为什么要一个介绍人夹在我和女孩之间呢,介绍成功了我还得请客吃饭,真的不爽啊。所以找家里人帮我介绍吧,我们将找女孩的要求写在纸上,交给家里人,就i等着女孩上门吧,以后想换一个也不用自己出马了。

public class Boy { 
      void Find Girl (Girl girl){
        girl.LoveMe()
      }

对于第一种情况, Boy自己建立自己的Girl,很难共享,只能单独使用,并完全的生命周期。

对于第二种情况,我们不希望出现额外的非标准的中介,这样会加剧对象之间的耦合程度

对于第三种情况,可能有人要说void Find Girl (Girl girl)这一句中,如果Boy不知道Girl对象是不会通过编译的,这和第一种情况又有什么区别呢.有两点,我们注意到不同类型女孩的属性可能不同,但是她们的行为能力(方法)基本无异,则我们可以运用面向接口编成的方法来包容我们对象的一些差异,更为重要的一点,我们接收到的Girl对象是已经存在的对象,是初始化完毕的对象,我们不需要在Boy中对Girl对象的一些属性进行设置,这些工作完全从Boy对象中被剥离开来了,实现了对象间的松耦合.

下面来看Spring中一个典型的反转控制的实现:

定义Action接口:

public interface Action {

public String execute(String str);

}

Action接口的两个实现UpperAction、LowerAction

public class UpperAction implements Action {

private String message;

public String getMessage() {

return message;

}

public void setMessage(String string) {

message = string;

}

public String execute(String str) {

return (getMessage() + str).toUpperCase();

}

}

public class LowerAction implements Action {

private String message;

public String getMessage() {

return message;

}

public void setMessage(String string) {

message = string;

}

public String execute(String str) {

return (getMessage()+str).toLowerCase();

}

}

Spring配置文件(bean.xml)

<beans>

<description>Spring Quick Start</description>

<bean id="TheAction"

class="net.xiaxin.spring.qs.UpperAction">

<property name="message">

<value>HeLLo</value>

</property>

</bean>

</beans>

测试代码

public void testQuickStart() {

ApplicationContext ctx=new

FileSystemXmlApplicationContext("bean.xml");

Action action = (Action) ctx.getBean("TheAction");

System.out.println(action.execute("Rod Johnson"));

}

分析以上代码,我们可以看到,UpperAction、LowerAction实现了Action接口,Action方法分别返回对象中私有变量message和接受到的参数str相连接所构成的字符串的大写形式和小写形式。

注意bean.xml配置文件中的内容,bean id="TheAction"

class="net.xiaxin.spring.qs.UpperAction" 这一句定义了一个bean,并将这个bean和一个对象相关联,这个对象正是UpperAction。<property name="message"><value>HeLLo</value> 这一句让我们在创建这个对象实例的时候能够自动将其message参数赋值为“Hello”。

接着看测试代码,ApplicationContext ctx=new

FileSystemXmlApplicationContext("bean.xml");这条语句使用配置文件实例化容器;Action action = (Action) ctx.getBean("TheAction");容器根据配置文件生成了一个action实例;System.out.println(action.execute("Rod Johnson"));我们赋给action一个参数Rod Johnson并输出action返回的结果。

最后,我们得到输出Hello Rod Johnson。

由此我们可以看出,容器的工作就是在创建bean时注入那些依赖关系(根据配置文件)。相对于bean自己来控制其实例化,直接在构造器中指定其依赖关系,控制在根本上发生了倒转,这就是IoC名字的由来。

wps_clip_image-32029

Spring的依赖注入机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以指定,从而在相当程度上降低了组件之间的耦合。