跟着柴毛毛学Spring(1)——纵观Spring

Spring根本任务

Spring的根本任务就是简化Java开发。 目前许多框架如果要使用他们,就必须要继承或实现这些框架的各种类。这使得框架与我们的程序耦合度过高。由于在我们的程序中加入了过多的框架代码,使得我们的代码看起来非常臃肿。 但Spring不是这样,它不会强迫你去实现或继承任何Spring的类,这样你的代码会非常清晰,而且完全看不出有Spring加入的痕迹。当然,如果使用了Spring注解,你的代码会稍稍留有Spring的痕迹,但与其他框架相比,即使使用了注解,Spring与我们程序的耦合度依然很低。

Spring特性一:依赖注入

面向接口编程

在了解依赖注入之前,首先要了解“面向接口编程”的思想。 首先来看如下代码: 以下代码创建了两个类A和B,A的构造函数中通过new创建B的对象,并调用B的show方法。 在一个类中,如果通采用new来创建另一个类的对象,将会使得这两个类过度耦合。

class A{
    private B b;
    public A(){
        b = new B();
        b.show();
    }
}

class B{
    public void show(){
        System.out.println("我是B");
    }
}

如果我们把B的对象作为参数传递给A的构造函数,即B对象的创建由类A调用者创建,而不是A自己创建,这样就能在一定程度上降低两个类的耦合度。代码如下:

class A{
    private B b;
    public A(B b){
        this.b = b;
        b.show();
    }
}

下面我们进一步降低这两个类降低耦合度: 类A不变,我们把类B抽象成一个接口,该接口中有一个抽象函数show。 然后我们分别定义接口B的两个实现类:B_1和B_2,并且分别实现show方法。

interface B{
    void show();
}

class B_1 implements B{
    public void show(){
        System.out.println("我是B_1");
    }
}

class B_2 implements B{
    public void show(){
        System.out.println("我是B_2");
    }
}

那么此时,如果调用者创建B_1的对象传递给A的构造函数的话,将会执行B_1的show方法,如果将B_2的对象传递给A的构造函数的话,就会执行B_2的show方法。因此,在A类代码不变的情况下,A的调用者可以自由地控制A究竟执行哪个B实现类的show方法,从而进一步降低了A和B的耦合度。 这种思想就是大名鼎鼎的“面向接口编程”!即:将接口作为函数的参数,在调用函数时,调用者可以灵活地决定究竟创建该接口的哪一个实现对象,从而达到在不改变函数代码的前提下,执行不同的代码

class A{
    private B b;
    public A(B b){
        this.b = b;
        b.show();
    }
}

依赖注入

在没学Spring之前,我们为一个引用赋值有以下三种方式: 1.通过new创建一个对象,然后赋给引用:

A a = new A();

2.通过函数的参数传递

void function(A aaa){
    A a = aaa;
}

3.将一个现成的对象赋给引用

A a = aaa;//假设aaa为一个现成的A对象

而现在,整个程序的所有对象都由Spring创建并管理。 Spring把类称为bean,每个bean都需要在XML文件中声明,为bean指定名字。 当我们需要一个对象的时候,只需调用Spring的context.getBean(“bean的名字”)即可获得该对象。而不是通过传统的new来创建。 这就是“依赖注入”。

依赖注入的优点

对于一个接口来说,它将会有很多实现类,这些实现类均含有相同的函数名和不同的函数实现。当一个实现类的对象赋给一个接口引用时,该引用可以访问实现类中实现的函数,如下所示:

SuperInterface a = new ImplmentClass_A();
a.show();

如果需要给a换一个实现类,仅需将new后面的类换掉即可,其他代码保持不变:

SuperInterface a = new ImplmentClass_B();
a.show();

但上述方法仍有缺点,如果需要更换实现类,还需要修改代码。能不能不修改代码就能更换实现类呢?Spring做到了! 所有负责所有对象的创建与管理,到底将哪个对象赋给SuperInterface a在配置文件中设置,而不需要修改代码了。 这就是Spring依赖注入的优点。

Spring特性二:面向切面编程

我们在开发一个函数的时候会发现,有些代码并不是这个函数的主要功能,但不得不去写,比如函数参数合法性的验证、日志的记录、事务管理等等。这些功能不是这个函数的主要功能,但为了增强程序的健壮性不得不去写。 而且,这些功能往往会导致重复的代码,每个函数的开头都要写一段参数合法性判断的代码,顿时感觉心好累。于是,Spring提出了面向切面编程。 我们可以把这些重复性的代码提取出来,封装到一个专门的类里面去。然后告诉Spring,某些函数执行的时候,先在函数的头或尾或中间切一刀,把刚才提取出来的代码加进去,然后再执行函数。这就是面向切面编程。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏飞雪无情的博客

Go语言经典库使用分析(四)| Gorilla Handlers 源代码实现分析

上一篇 Go语言经典库使用分析(三)| Gorilla Handlers 详细介绍 中介绍了Handlers常用中间件的使用,这一篇介绍下这些中间件实现的原理...

603
来自专栏木木玲

设计模式 ——— 职责链模式

1093
来自专栏菜鸟计划

webpack前言:前端模块系统的演进

前端开发和其他开发工作的主要区别,首先是前端是基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器,这些资源是通过增量加载的方式运行到浏览器端, ...

3305
来自专栏程序员宝库

我所理解的接口设计

前言 自己做接口开发的时间也算不短了(三年),想写这篇文章其实差不多已经有一年多的时间了。我将从下面的方向来对我所理解的接口设计做个总结: 接口参数定义 -> ...

2877
来自专栏移动开发面面观

Java学习笔记——内存管理Java内存管理

953
来自专栏java一日一条

30 分钟 Java Lambda 入门教程

Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在Java领域中发展较慢,直到java8,才开始支持Lambda。

814
来自专栏Java帮帮-微信公众号-技术文章全总结

Java代码效率优化【面试+提高】

JAVA代码效率优化 最近在想自己编程时是否注意过代码的效率问题,得出的答案是:没有。代码只是实现了功能,至于效率高不高没怎么关注,这应该是JAVA程序员进阶...

38113
来自专栏Golang语言社区

golang中发送http请求的几种常见情况

整理一下golang中各种http的发送方式 最初的一些项目中,很多的地方都使用到了golang发送http请求,之后再对请求收到的结果进行一些处理,所用到的模...

4788
来自专栏架构说

man epoll的惊喜

今日问题: 0.1ms socket a 过来一起个请求 a 0.2ms socket b 过来一起个请求 b epoll_wait 返回结果是什么 我...

3468
来自专栏性能与架构

Mysql Join语句的优化

1. 尽可能减少Join语句中Nested Loop的循环总次数 最有效的办法是让驱动表的结果集尽可能地小,这也正是在本章第二节中所提到的优化基本原则之一——“...

3346

扫描关注云+社区