IoC(Inversion of Control),这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关 系。
以前,我们是这样创建对象的:
/* //普通调用 IPersonDAO persondao=new PersonDAO(); persondao.Save(); */ /* //工厂方式调用 IPersonDAO persondao = DataAccess.CreatePersonDAO(); persondao.Save(); */
先说第一种直接new的方式,这种方式将对象的创建过程暴露出来,接下来,我们意识到这种问题之后,或许会将这个对象的创建过程封装成一个方法来调用,这样屏蔽掉了对象的创建细节,这对于创建复杂对象是有极大好处的。
但是这两种方式都是由对象来负责对象的创建的,当然,创建完了之后,还要由我们手动维护它的生命周期和它与其他类直接的引用关系等。如果有这么一种方式,一,可以替我避免掉复杂对象的创建过程,使我免受各种参数的困扰;二,替我维护对象的生命周期和它在系统中的关系;我要做的只是在我需要这个类的时候它出现,我不需要它的时候也不用担心它。
于是,容器这种东西出现了,spring不过是实现容器思想的一种东西。
这时候,对象的创建,销毁,处理各种引用关系都交给spring来处理。所有的类都会在spring容器中登记,告诉spring这是个什 么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把对象交给其他需要它的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象 都被spring控制,所以这叫控制反转。
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统 运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。 --来自百度
其实想想注入原理,无论.Net还是Java,都是反射。反射从表面上看是根据一个字符创建什么东西,这个东西可以是程序集,类,属性,方法。。。反射带来的好处就是动态性,在复杂的运行环境下,我不知道系统运行到某个时刻需要一个什么东西,这时候,我们就可以运用反射来实现动态的创建过程,与反射带来的灵活性相比,我们几乎可以忽略掉它带来的性能问题。
首先来看下我们的Demo结构:
为了在console中使用sping,需加入加入spring的引用:
接口类:
namespace DemoOne { public interface IPersonDAO { /// <summary> /// Saves this instance. /// </summary> /// <remarks>创建者:刘慧超; 创建时间:2015-09-12 20:45:25</remarks> void Save(); } }
实现类:
namespace DemoOne { public class PersonDAO:IPersonDAO { /// <summary> /// Saves this instance. /// </summary> /// <remarks>创建者:刘慧超; 创建时间:2015-09-12 20:45:20</remarks> public void Save() { Console.WriteLine("啦啦啦啦啦啦。。。。。。。保存啦。。"); } } }
接下来简单说下常见的两种配置文件+XML怎么配置spring:
1,单独建立一个xml文件,里面保存了spring要管理的类的信息,如上objects.xml:
<?xml version="1.0" encoding="utf-8" ?> <objects > <description></description> <object id="PersonDAO" type="DemoOne.PersonDAO,DemoOne"/> <!-- 配置要生成的类--> </objects>
然后是应用程序配置文件:
<?xml version="1.0" encoding="utf-8"?> <configuration> <!--配置处理节点的处理类--> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/> <section name ="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/> </sectionGroup> </configSections> <!-- spring配置--> <spring> <!--配置方式一:使用外部xml文件作为对象配置,注意:外部XML要复制到生成路径--> <context> <resource uri="file://objects.xml"></resource> </context> </spring> </configuration>
简单调用代码:
//使用了spring IApplicationContext iac = ContextRegistry.GetContext(); IPersonDAO dao = iac.GetObject("PersonDAO") as IPersonDAO; if (dao!=null) { dao.Save(); Console.WriteLine("spring测试成功"); Console.ReadKey(); }
当然,我们也可以将类的配置信息全部写在configuration里面,不使用外部xml:
<?xml version="1.0" encoding="utf-8"?> <configuration> <!--配置处理节点的处理类--> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/> <section name ="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/> </sectionGroup> </configSections> <!-- spring配置--> <spring> <!--配置方式二:将所有配置保存在应用程序配置文件中--> <context> <resource uri="config://spring/objects"></resource> </context> <objects> <object id="PersonDAO" type="DemoOne.PersonDAO,DemoOne"/> <!-- 配置要生成的类--> </objects> </spring> </configuration>
另外,也可以使用编程方式,直接加载xml方式,或者是xml跟config混合使用方式配置spring。