Spring.net依赖注入及环境配置
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 在实现注入对象的实例化时候,将调用类的默认构造函数。