使用Spring.Net进行WebService开发(三)Spring.Net容器相关知识

来源:互联网 发布:centos apache配置 编辑:程序博客网 时间:2024/06/07 02:13

本来准备这一篇说说NHibernate,但是考虑到如果有没有接触过Java的Spring框架的同学,可能有很多地方都不明白,所以决定把一些基本概念说明一下。

首先来说说什么是Spring容器?

当你在一个对象中需要使用另一个对象的时候,最直接的办法当然是把它new出来。好了,现在我加一个限制,这个对象里有一些内部状态,我希望这些状态共享给所有访问这个对象的人,此时又怎么做呢?给需要共享的数据和方法加static就好了。好,现在已经满足前面的需求了,现在新的需求又来了,如果需要通过继承来扩展这些共享数据和方法呢?现在已经不可能了,因为选择静态就等于失去了多态。所以,一般工具类会采用这种方式,比如Math类,一般工具类不需要进行扩展和修改,所以这样可行。

除了这一点,static所能控制的只有对应用程序级别的限制,也就是说这个对象要么大家各用各的,要么就都用同一个,不能再分到更细的范围(scope),比如我希望同一个用户使用同一个对象,不同用户使用不同对象,因此容器便出现了。

想到这一点很简单,既然大家都要用,那我就把它放到一个公共的地方去,大家都到那去取,这个地方就是容器,容器可以为对象的范围做出更多的控制。

singleton 每次获取都返回同一个实例,就是单例prototype 每次获取都返回新的实例,就是每次都newrequest 对一个HTTP请求,每次获取都返回同一个实例session 对一个HTTP session,每次获取都返回同一个实例application 对一个web application,每次获取都返回同一个实例

前两者一般在桌面程序中使用,后三者一般在web程序中需用,使用后三者需要Spring.Web

<object id="Foo" type="SpringNetDI.Foo" /><object id="Foo" type="SpringNetDI.Foo" singleton="true" />

桌面程序中以上两种写法等价,就是singleton

<object id="Foo" type="SpringNetDI.Foo" singleton="false"/>
以上写法就是prototype

在web程序中,使用scope来设置相应范围,如:

<object id="Foo" type="SpringNetDI.Foo" scope="prototype"/>


好了,现在我们已经知道如何将对象放进容器中了,那么如何将对象取出呢,是我们自己来取吗?

根据IoC(Inversion of Control)概念,我们需要的对象应该是容器主动提供的,即依赖注入(DI)。

当然,实现依赖注入需要一个前提,就是对象不能离开容器管理范围,即需要被完成注入的对象必须由容器来创建,这时容器才能把它需要的对象注入进去,当然,这些被注入的对象也来自容器。

Spring.Net为我们提供了多种注入手段,最常用的是构造函数注入和属性注入,在下面这个例子中,Foo和Bar通过不同方式注入到FooBar对象中。

通过构造函数注入时,我们一般只是在构造时使用该对象,此后便不再需要该对象。如果后续需要持续使用该对象,那么一般通过属性注入,这一点不得不说C#的自动属性要比Java的get、set方法方便多了。

public interface ICall{    void Call();}public class Foo : ICall{    public Foo()    {        Console.Out.WriteLine("Foo Constracted.");    }    public void Call()    {        Console.Out.WriteLine("Foo Called.");    }}public class Bar : ICall{    public Bar()    {        Console.Out.WriteLine("Bar Constracted.");    }    public void Call()    {        Console.Out.WriteLine("Bar Called.");    }}public class FooBar{    public ICall Call { get; set; }    public FooBar(ICall call)    {        call.Call();    }    public void CallInternal()    {        Call.Call();    }}

配置如下:

  <object id="Foo" type="SpringNetDI.Foo" />  <object id="Bar" type="SpringNetDI.Bar" />  <object id="FooBar" type="SpringNetDI.FooBar">    <!--属性注入-->    <property name="Call" ref="Foo" />    <!--构造函数注入-->    <constructor-arg name="call" ref="Bar"/>  </object>


原创粉丝点击