Spring这个思想,已经推出很多年了。

刚开始的时候,首先是在Java里面提出,后来也推出了.net的版本。

Spring里面最主要的就是控制反转(IOC)和依赖注入(DI)这两个概念。

网上很多教程都有详细的介绍这两个概念和相关的教程,但是至于什么时候会用得到Spring,为什么要使用Spring,提到的教程不多。

经过研究之后,决定写个Demo,供大家了解。

本人是.net程序员,所以会通过下面这个.net项目进行说明,

开发软件:VS2017,Framework版本:4.0

首先,介绍一下这个项目的基本信息,这是一个通过用户的Id查找用户信息的Demo,默认,我们是到Sql数据库中进行查找。

解决方案里,总共有3个项目,分别是Cong.Dao,Cong.Model,ConsoleApp

其中,Model是最简单的,里面只有一个User类,用于表示一个用户,有用户的Id、Name、Age、Phone、Remark,关键是Remark属性,用于区分使用Spring的前后对比。

 namespace Cong.Model
{
public class User
{
public string Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Phone { get; set; } public string Remark { get; set; } public User(string id, string name, int age, string phone, string remark)
{
this.Id = id;
this.Name = name;
this.Age = age;
this.Phone = phone;
this.Remark = remark;
} public string Hello()
{
return string.Format("我是{0},联系电话是{1},数据来源于:{2}。", Name, Age, Remark);
}
}
}

Cong.Dao里有一个接口IUserDao和一个类UserSqlDao,接口是为了扩展性,类是用于作为数据访问层,但这里并不是真的连接到数据库,只是写固定代码来模拟,代码如下:

 namespace Cong.Dao
{
public interface IUserDao
{
User GetUserById(string id);
}
}
 namespace Cong.Dao
{
public class UserSqlDao : IUserDao
{
public User GetUserById(string id)
{
User ui;
if (id.Equals(""))
{
ui = new User(id, "德华", , "", "SQL");
}
else
{
ui = new User(id, "学友", , "", "SQL");
} return ui;
}
}
}

ConsoleApp就是一个控制台,我们通过输入用户的Id,就能到数据库查出用户的信息。

 namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.Write("输入用户Id:");
string id = Console.ReadLine();
Console.WriteLine(); IUserDao ud;
ud = new UserSqlDao(); User user = ud.GetUserById(id);
Console.WriteLine(user.Hello()); Console.ReadKey();
}
}
}

运行结果如下:

到这里,全部的代码结束,可以正常运行了。

但是,如果今后,由于其他原因,需要把数据库变更为Oracle,除了数据需要迁移以外,我们的程序也要进行修改。

修改的方法比较简单,就是新建一个UserOracleDao,同样要继承IUserDao,

 namespace Cong.Dao
{
public class UserOracleDao : IUserDao
{
public User GetUserById(string id)
{
User ui;
if (id.Equals(""))
{
ui = new User(id, "德华", , "", "Oracle");
}
else
{
ui = new User(id, "学友", , "", "Oracle");
} return ui;
}
}
}

而在控制台的代码中,需要把new UserSqlDao() 修改为new UserOracleDao()。

但是,这里有些问题:

1、新建一个Dao类,是必须要的;

2、需要修改主程序的代码,而由于这只是个Demo项目,实际的开发项目中,代码比这个Demo的多得多,可能也会有Bll层,我们就要修改多个类的代码了,很有可能会改错,这不便于维护;

3、如果需求是,Sql和Oracle需要同时存在,使用过程中,由用户选择决定,以后可能还有更多的数据库追加,那么我们需要修改的代码,就变得更多更复杂了。

所以,这个时候就可以使用Spring了。

为什么使用Spring?

Spring可以降低代码的耦合度,便于扩展,便于维护。

使用Spring有什么好处?

可以让我们在后期维护程序时,大幅度减少修改代码的量,降低出错的机率。

直接上代码吧。

首先,我们还是需要建好上面说到的UserOracleDao类。

然后,在ConsoleApp项目中,通过Nuget安装“Spring.Core”,并且新建一个App.config,

 <?xml version="1.0" encoding="utf-8" ?>
<configuration> <configSections>
<sectionGroup name="spring">
<!--跟下面Spring.Net节点配置是一一对应关系-->
<section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/>
</sectionGroup>
</configSections> <!--Spring.Net节点配置-->
<spring>
<!--容器配置-->
<context>
<resource uri="config://spring/objects"/>
</context>
<objects>
<!--objects里面放容器的所有节点-->
<description>An example that demonstrates simple Ioc features.</description>
<!--name 必须要唯一的,type = 类的全名称,所在的程序集-->
<object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object> </objects>
</spring> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup> </configuration>

控制台的代码修改为:

 namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.Write("输入用户Id:");
string id = Console.ReadLine();
Console.WriteLine(); IUserDao ud; //IOC
IApplicationContext ctx = ContextRegistry.GetContext();
ud = (IUserInfoDao)ctx.GetObject("UserDao"); User user = ud.GetUserById(id);
Console.WriteLine(user.Hello()); Console.ReadKey();
}
}
}

解释一下,在配置文件中,加入了<object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object>,定义了一个键值对,键是用UserDao,对应的是要用的类,就是UserSqlDao,然后在控制台中,通过IOC容器,加载键为UserDao的值,new一个UserSqlDao的类,这个过程中,代码只会以键为主,没有涉及具体的类。至于实际使用时,new哪一个类,全凭配置文件来定义。

例如,如果我想换为Oracle,就把值修改为“Cong.Dao.UserOraclelDao,Cong.Dao”

这就与传统的写法有很大的差别,传统的写法是通过代码来指定用哪个类,Spring是通过写接口,固定的代码,在代码中调用配置文件中的键,而真正决定用哪个类,是由配置文件来决定的。这就叫做控制反转。

IOC容器可以理解为,我建立一个容器,用于new类,但是我并不关心具体有什么类。反正当我要使用的时候,我往容器里传入键,在配置文件里写入键值对,IOC容器就能返回我要的类。

这种做法,最大的优点就是,new的动作,都集中在配置文件中,一目了然,管理方便。

类似的框架还有Mybatis。

当我们开发一套程序时,为了以后的扩展性,可以加入Spring,我们可以为二次开发人员提供接口,他们就可以自己写扩展类,加入配置文件。

也可以把扩展的类,全部做成选项功能,让用户去选择。这个功能,对于Web项目,十分有用。

想下载Demo源代码的朋友,可以到以下地址:

https://download.csdn.net/download/cycong108/10974093

(说明:由于Spring.net的包有23M,为了下载方便,我已经删除了安装包,需要运行的朋友,请自行下载安装,版本如下图)

写的内容有点乱,如有发现不足的地方,欢迎指出。

Spring.net的Demo项目,了解什么是控制反转的更多相关文章

  1. 码农小汪-spring框架学习之2-spring IoC and Beans 控制反转 依赖注入 ApplicationContext BeanFactory

    spring Ioc依赖注入控制反转 事实上这个东西很好理解的,并非那么的复杂. 当某个Java对象,须要调用还有一个Java对象的时候(被依赖的对象)的方法时.曾经我们的做法是怎么做呢?主动的去创建 ...

  2. spring的依赖注入(DI)、控制反转(IOC)和面向切面(AOP)

    在spring的配置文件增加 <context:component-scan base-package="com.jmu.ccjoin.service"/> <c ...

  3. Spring的基本应用(1):依赖以及控制反转

    在说到这里的时候,首先要说下程序的耦合和解耦,以便对上节做一个解释. 一.程序的耦合和解耦 1.程序的耦合性(Copling) (1)程序的耦合性,也叫做耦合度,是对模块之间关联程度的度量,耦合性的强 ...

  4. Spring Security OAuth2 Demo

    Spring Security OAuth2 Demo 项目使用的是MySql存储, 需要先创建以下表结构: CREATE SCHEMA IF NOT EXISTS `alan-oauth` DEFA ...

  5. spring三大核心学习(一)---控制反转

    记得当年大学时候,java的企业级框架还是ssh的天下(spring,struts和hibernate),但是现在,感觉spring已经完全把那两个框架甩在后边了.用spring的人越来越多,用str ...

  6. Spring详解(二)------IOC控制反转

    我相信提到 Spring,很多人会脱口而出IOC(控制反转).DI(依赖注入).AOP等等概念,这些概念也是面试官经常问到的知识点.那么这篇博客我们就来详细的讲解 IOC控制反转. ps:本篇博客源码 ...

  7. spring核心思想:IOC(控制反转)和DI(依赖注入)

    Spring有三大核心思想,分别是控制反转(IOC,Inversion Of Controller),依赖注入(DI,Dependency Injection)和面向切面编程(AOP,Aspect O ...

  8. 控制反转是Spring框架的核心。

    早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题.他总结出是依赖对象的获得被反转了.基于这个结论,他为控制反转创造了一个更好的名字:依赖注入.许多非凡的应用(比H ...

  9. spring 控制反转与依赖注入原理-学习笔记

    在Spring中有两个非常重要的概念,控制反转和依赖注入:控制反转将依赖对象的创建和管理交由Spring容器,而依赖注入则是在控制反转的基础上将Spring容器管理的依赖对象注入到应用之中: 所谓依赖 ...

随机推荐

  1. XML之序列化C#实体类,DataTable,List

    1. static void Main(string[] args) { #region 实体类 Request patientIn = new Request(); patientIn.System ...

  2. 安装完Python之后,如何设置Python环境变量

    人生苦短,我用Python.最近有许多加群的萌新在咨询Python安装的事宜,Python安装问题不大,可以戳这篇文章:.本以为安装Python之后就可以万事大吉,高枕无忧了,往命令行中输入pytho ...

  3. Felx之HTTPService

    获取并显示数据 为了向我们的程序提供数据,Adobe Flex包含特别为与HTTP服务器,网络服务或者是远程对象服务(Java对象)进行交互的而设计的组件.这些组件被称之为远程过程调用(RPC)服务组 ...

  4. 微信小程序官方文档中的加密算法

    用Nodejs来算一下:

  5. 解决MyEclipse中安装或升级ADT之后SDK Target无法显示的问题

        故障现象,在MyEclipse里面安装完最新的android sdk和ADT之后,无法新建项目,Build Target为空,显示一直在loading.即如下面图里面显示的,Target Na ...

  6. boost.property_tree的高级用法(你们没见过的操作)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 前一阵写项目,终于将这个boost下的xml读取类完成了,由于网上对property_trees的讲解很少,最多也就到get_child这个层面, ...

  7. 【Henu ACM Round#14 F】 President and Roads

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 处理出起点到任意点的最短路以及最短路条数=>dis[0][i],cnt[0][i] 然后 把所有的边反向 处理出在反图上终点到 ...

  8. HDU——T 1506 Largest Rectangle in a Histogram|| POJ——T 2559 Largest Rectangle in a Histogram

    http://acm.hdu.edu.cn/showproblem.php?pid=1506  || http://poj.org/problem?id=2559 Time Limit: 2000/1 ...

  9. linux杂谈(十八):DNSserver的配置(一)

    1.DNSserver简单介绍 域名系统(英文:Domain Name System,縮寫:DNS)是因特网的一项服务. 它作为将域名和IP地址相互映射的一个分布式数据库,可以使人更方便的訪问互联网. ...

  10. (七十一)关于UITableView退出崩溃的问题和滚动究竟部的方法

    [TableView退出崩溃的问题] 近期在使用TableView时偶然发如今TableView中数据较多时,假设在滚动过程中退出TableView到上一界面.会引起程序的崩溃.经过网上查阅和思考我发 ...