antlr.runtime.dll |
Common.Logging.dll |
Spring.Core.dll |
Spring.Web.dll |
Spring.Data.dll |
Spring.Services.dll |
Spring.Aop.dll |
Spring.Aspects.dll |
Spring 通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了 IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为 IoC 与 JNDI 相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
我的理解是:Spring 将我们要用到的类配置在一个 XML 文件里,例如对一个操作 User 对象的服务类 UserService,对于 UserService 我们可以有不同的实现,可以使用 Oracle 或是 MySQL 数据库,我们可以统一接口写一个 IUserService 接口,共同实现获取 User 对象的方法。
User 类代码:
public class User {
// ID
private string id;
public string Id {
get { return id; }
set { id = value; }
}
// Name
private string name;
public string Name {
get { return name; }
set { name = value; }
}
//
public User(string id, string name) {
this.name = name;
this.id = id;
}
//
public User() { }
}
IUserService 接口:
public interface IUserService {
User GetUser();
}
接口写好之后,我们分别使用两种不同的逻辑层服务类实现 IUserService。
使用 Oracle 数据库的实现:
public class UserServiceOracleImpl : IUserService {
public User GetUser() {
return new User( " 200607011 " , " jordon(Oracle) " );
}
}
使用 MySQL 数据库的实现:
class UserServiceMySQLImpl : IUserService {
public User GetUser() {
return new User( " 200607011 " , " jordon(MySQL) " );
}
}
首先在 Web.config / App.config 文件中,配置相关 Spring 自身配置。
<? xml version = " 1.0 " ?>
< configuration >
< configSections >
< sectionGroup name = " spring " >
< section name = " context " type = " Spring.Context.Support.WebContextHandler, Spring.Web " />
< section name = " objects " type = " Spring.Context.Support.DefaultSectionHandler, Spring.Core " />
< section name = " parsers " type = " Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core " />
</ sectionGroup >
</ configSections >
< spring >
< parsers >
< parser type = " Spring.Data.Config.DatabaseNamespaceParser, Spring.Data " />
</ parsers >
< context >
< resource uri = " ~/Configs/CommonService.xml " />
< resource uri = " ~/Configs/Objects.xml " />
</ context >
</ spring >
< appSettings />
< connectionStrings />
< system.web >
< compilation debug = " true " >
< assemblies >
< add assembly = " System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089 " />
</ assemblies >
</ compilation >
< authentication mode = " Windows " />
< httpHandlers >
< add verb = " * " path = " *.aspx " type = " Spring.Web.Support.PageHandlerFactory, Spring.Web " />
</ httpHandlers >
< httpModules >
< add name = " SpringModule " type = " Spring.Context.Support.WebSupportModule, Spring.Web " />
</ httpModules >
</ system.web >
</ configuration >
配置好之后,我们就需要在项目中引用 Spring 的相关程序集文件了。
< context >
< resource uri ="~/Configs/CommonService.xml" />
< resource uri ="~/Configs/Objects.xml" />
</ context >
这里的配置表示 Spring 将从这些 XML 文件里读取配置文件,我们要注入的对象可以写在 XML 文件里,然后将 XML 文件路径
配置在 <spring> 中的 <context> 节点下。
4. 依赖注入
我们现在将实现了 IUserService 接口的 UserServiceOracleImpl 类配置在 CommonService.xml 文件中:
<? xml version="1.0" encoding="utf-8" ?>
< objects xmlns ="http://www.springframework.net"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd" >
< object id ="UserService" type ="SpringNet.BLL.UserServiceOracleImpl, SpringNet.BLL" >
</ object >
</ objects >
5. 使用注入的服务类
public partial class _Default : System.Web.UI.Page {
// Fields
private IUserService userService;
public IUserService UserService {
set { this .userService = value; }
}
protected void Page_Load( object sender, EventArgs e) {
IApplicationContext ctx = ContextRegistry.GetContext();
userService = ctx.GetObject( " UserService " ) as IUserService;
User user = userService.GetUser();
string s = string .Format( " ID:{0} Name:{1} " , user.Id, user.Name);
Response.Write( " 注册服务<br/> " );
Output(s);
}
private void Output( string s) {
s = string .Format( " <span class='span'>{0}</span><br/><br/> " , s);
Response.Write(s);
}
}
在这里我们只需要将用到的服务类声明一下就可以了。
如果我们要想使用 UserServiceMySQLImpl 服务类,直接修改 CommonService 里配置即可:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< objects xmlns = " http://www.springframework.net "
xmlns:xsi = " http://www.w3.org/2001/XMLSchema-instance "
xsi:schemaLocation = " http://www.springframework.net
http: // www.springframework.net/xsd/spring-objects.xsd">
< object id = " UserService " type = " SpringNet.BLL.UserServiceMySQLImpl, SpringNet.BLL " >
</ object >
</ objects >
因为是 UserServiceMySQLImpl 与 UserServiceOracleImpl 实现了共同的接口 IUserService ,根据多台的性质,父类对象
指向子类引用,所以在 Default.aspx.cs 文件中,声明的 IUserService UserService 将调用其实现类的 GetUser() 方法。
通过这样的配置,我们可以不用修改程序代码,只要修改配置文件就行了。
6. 注入对象实体
对于单例对象,或是静态的对象,以后在项目的实施过程中,需要重新配置的,也可以使用 Spring.net 进行配置,以及相关构造
方法参数的配置,以及类属性的配置。
下面我们将注入一个 User 实体类,以及注入它的两个属性 Id 和 Name。
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< objects xmlns = " http://www.springframework.net " >
< object id = " Admin " type = " SpringNet.Model.User, SpringNet.Model " >
< property name = " Id " value = " EDNY20090114 " />
< property name = " Name " value = " 晴天 " />
</ object >
</ objects >
配置好之后,在 Default.aspx.cs 文件里,我就可以使用:
User user2 = ctx.GetObject("Admin") as User;
来获取注入的实行对象了。
7. 注入集合对象
集合对象可以通过 list 来实现对象的注入,可以注入类对象实现,也可以注入 int 、string 这样的非引用值类型的集合。
我们声明一个 Facebooks 的类,类中将使用两个集合对象,一个是类对象集合,一个是 int 类型集合:
namespace SpringNet.Model {
public class Facebooks {
// Friends
private List < User > friends;
public List < User > Friends {
get { return friends; }
set { friends = value; }
}
// Ages
private List < int > ages;
public List < int > Ages {
get { return ages; }
set { ages = value; }
}
//
public Facebooks() { }
//
public Facebooks(List < User > fs) {
this .friends = fs;
}
}
}
Facebooks 类我们将使用有参数的构造函数来演示,这样也可以在配置文件中,配置构造参数来进行注入对象的实例化。
配置文件如下:
<? xml version="1.0" encoding="utf-8" ?>
< objects xmlns ="http://www.springframework.net" >
< object id ="Admin" type ="SpringNet.Model.User, SpringNet.Model" >
< property name ="Id" value ="EDNY20090114" />
< property name ="Name" value ="晴天" />
</ object >
< object id ="Me" type ="SpringNet.Model.User, SpringNet.Model" >
< property name ="Id" value ="ME20090114" />
< property name ="Name" value ="薛明" />
</ object >
< object id ="FaceBooks" type ="SpringNet.Model.Facebooks, SpringNet.Model" >
< constructor-arg name ="fs" >
< list element-type ="SpringNet.Model.User, SpringNet.Model" >
< ref object ="Admin" />
< ref object ="Me" />
</ list >
</ constructor-arg >
< property name ="Ages" >
< list element-type ="int" >
< value > 1992 </ value >
< value > 1998 </ value >
< value > 2000 </ value >
</ list >
</ property >
</ object >
</ objects >
注:在进行 Facebooks 的构造参数的配置时,<constructor-arg name="fs">这里的 fs 就是 Facebooks 类中构造参数的名字。
同样的我们可以在 Default.aspx.cs 文件中:通过 Facebooks fbs = ctx.GetObject("FaceBooks") as Facebooks 来获取注入的对象。
通过 fbs.Ages 可以获取 int 集合对象等等。
最后程序运行截图:
8. 需要注意的地方
在注入对象时候,如果我们没有提供构造参数的配置,只是配置了注入对象的各个属性,我们就需要给注入的类实现一个无参数的构造函数,
或是对象里不要写任何构造函数,Spring 在实现注入对象的实例化时候,将调用类的默认构造函数。