spring-GetStarted-从了解最基本的功能开始

上手一个业务型的项目也好,学习功能型的工具、框架也好,首先应该去了解它的功能,理解创建开发这个项目的出发点。要理解spring的功能、理念,不妨想下没有它我们是怎么做的。
注:本篇不是入门编码指南。文章里的代码也只是帮助理解的一个例子。

案例介绍

下文中我们要用到一个例子:办事窗口ServiceWindow和柜员Clerk。办事窗口能提供付款pay、咨询consult业务,由柜员来完成。公司目前有柜员小张Zhang。

这个业务用代码很简单,如下:

  • 办事窗口
class ServiceWindow{
    private Clerk clerk = new Zhang();
    
    public void pay(){
        cleck.pay();
    }

    public void consult(){
        cleck.consult();
    }
}
  • 柜员
interface Clerk{
    public void pay();
    public void consult();
}
  • 小张
class Zhang implements Clerk{
    public void pay(){
        //此处是完成支付的代码
    }
    public void consult(){
        //此处是完成咨询的代码
    }
}

关于“依赖”

我们知道JAVA是面向对象的语言,功能都封装在一个个类中。系统实际运行时,要通过类或对象调用方法来完成功能。类A中保存了另一个类B的对象的引用,调用B的方法来完成功能,我们就称A依赖B。比如上面的办事窗口实例中,办事窗口就依赖柜员。
在调用方法前,必须完成依赖的实例化,否则毫无疑问会报错。

实例中的问题

办事窗口案例中,我们在ServiceWindow类中是直接调用Zhang的构造方法完成了柜员对象的实例化。这个就是我们口头上说的“代码写死”。
那写死都有什么问题?
假设我们的办事窗口功能运行非常完美,公司要你把这块功能打成一个jar包,以后其他系统要用的话直接引入jar包。那现在就有问题了,每个柜台的柜员不一样啊,我们代码里现在“写死”了柜员是小张的。那现在公司B柜员是小李,怎么办?那就能修改代码重新编译ServiceWindow。
“写死”的问题就在于依赖的实现被固定了,而实际上它是不确定的。

如何解决

既然“写死”不可取,那在调用方这边就不能直接创建依赖的对象。把调用构造方法部分去掉。
当然之前说过,实现是必须要的,否则肯定会报错。
我们可以让ServiceWindow提供一个带柜员参数的构造方法;或者ServiceWindow提供一个clerk属性的set方法。或者干脆用反射来给clerk赋值。总之就是把依赖的创建从调用方剥离出来,在其他地方创建clerk对象,然后再想办法跟ServiceWindow中的引用关联(这个其实就是依赖注入)。

class ServiceWindow{
    private Clerk clerk;
    public ServiceWindow(Clerk clerk){
        this.clerk = clerk;
    }
    public void setClerk(Clerk clerk){
        this.clerk = clerk;
    }
    public void pay(){
        cleck.pay();
    }

    public void consult(){
        cleck.consult();
    }
}
//在其他某处:
Clerk zhang = new Zhang();
//1.通过构造方法
ServiceWindow serviceWindow = new ServiceWindow(zhang);
//2.或者通过set方法
ServiceWindow serviceWindow = new ServiceWindow();
serviceWindow.setClerk(zhang);

为何需要spring

仔细想想上面提到的问题是不是随处可见?一个大型系统中,肯定有大量的依赖关系存在,大部分时候都没法写死,必须像上面那样通过依赖注入的方式解决。既然一个功能大量存在,那就应该考虑把这个功能抽出来做成一个单独的工具或框架。这不就是spring吗。

spring最基本功能

下面我们就可以介绍SPRING了。你现在打开SPRING官网,会发现里面东西非常多。如果要说一个最基本的,那肯定就是IOC容器。IOC,Inversion Of Control,控制反转。在介绍软件设计原则的书里可以看到它。具体的说就是类把它依赖的对象的创建的权力交了出来。这样的好处就是能达到我们经常说的高内聚低耦合的目标:每个类只关注自己功能的实现,如果要和其他类合作,也只通过接口的方式提要求,至于其他类怎么实现,互相之间不关心(或者说互相透明)。
IOC容器要完成两个功能:对象的创建,和依赖关系的建立。我们开发人员要做的就是:告诉SPRING哪些类交给它管理,以及类与类之间都有什么依赖关系。

posted @ 2022-06-14 16:39  虾饺的棉毛裤  阅读(56)  评论(0编辑  收藏  举报