为什么使用Spring

Posted Java全栈从0到1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么使用Spring相关的知识,希望对你有一定的参考价值。

Spring的根本使命:简化JAVA开发

几个概念:

POJO:Plain Old Java Object,普通的Java对象。指只有属性、get、set等方法,不包含复杂逻辑的Java类。

JavaBean:一种可重用组件,是指符合JavaBean规范的类。JavaBean规范主要有以下几条(仅从网络信息摘取过来,有待商榷)

类必须是具体的和公共的,并且具有无参数的构造器。

提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取

属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。

EJB:Enterprice JavaBean,是指符合Java企业级应用规范的类

为了快速开发企业级应用,Java提出了EJB,但是太重量级,并不好用;Spring技术则提供了一种方案,仅基于POJO又能实现EJB或其它企业级规范JAVA对象才有的功能,使企业级开发变得更加轻量级,简单;另外Java也看到了Spring技术的优势和好处,也使用Spring技术的原理,改进了原来的EJB,使其更加简单好用;目前为止,Spring技术还是比EJB技术更加好用。

另外,Spring还在不断进步中,移动开发、社交API集成、NoSQL数据库,云计算以及大数据等领域,Spring都一直创新,用更加高效简单的方式来提供这些领域的解决方案

Spring中把应用组件(类)也称为Bean或者JavaBean,但是Spring指的是任何POJO,所以文章中所有Bean或JavaBean不一定符合JavaBean规范,可能只是一个POJO

Spring的几个关键策略

为了简化Java开发,Spring使用了以下几个关键策略

1、基于POJO的轻量级和最小侵入编程

  通常一个类应用Spring技术,不需要引用Spring;即使是最坏的情况,也只需要用到Spring注解,不会有Spring的代码出现在一个类中。从而保证应用中的类仍是POJO

2、基于依赖注入和面向接口实现松耦合

  DI:Dependency Injection 依赖注入

  在传统编程中,难免会有以下这种编程情景(多个类交互)

public class DamselRescuingKnight implements Knight {

  private RescueDamselQuest quest;

  public DamselRescuingKnight() {
    this.quest = new RescueDamselQuest();
  }

  public void embarkOnQuest() {
    quest.embark();
  }

}

  DamselRescuingKnight中,通过new 创建了一个RescueDamselQuest实例,2个类形成了紧耦合。

  其中的依赖关系是DamselRescuingKnight依赖RescueDamselQuest,而且限制了embarkOnQuest方法的实现

  而且,无法对DamselRescuingKnight进行单元测试,因为embarkOnQuest方法需要调用RescueDamselQuest的embark方法,而仅在这个方法内,并没有这个方法的实现

  耦合的两面性:必须的(复杂逻辑必然有多个类进行交互)、过于耦合将导致难以测试、复用、难以理解

  依赖注入:将对象的依赖关系交给第三方来进行创建和管理

public class BraveKnight implements Knight {

  private Quest quest;

  public BraveKnight(Quest quest) {
    this.quest = quest;
  }

  public void embarkOnQuest() {
    quest.embark();
  }

}

  上面使用了依赖注入的一种方式:构造器注入;而且传入的是一个Quest接口,对象和依赖对象的具体实现没有耦合关系,就形成了松耦合。

  而且,此情况下,可以使用mock(一种测试方式,具体自行学习)实现单元测试。

  Spring可以作为一个依赖注入容器,通过不同方式注入,也有相应的配置,装配策略,留到后面讲解。

3、基于切面和惯例进行声明式编程

  AOP:Aspect Oriented Programming,面向切面编程

  DI负责让互相协作的组件实现松耦合,而AOP则允许把遍布程序各处的功能分离出来形成可重用组件。

  可以把切面想象成很多组件上的一个外壳,借助AOP,可以使用各种功能层包裹核心业务层,以声明的方式灵活应用到系统中,核心应用中与这些功能层没有耦合,保证了POJO的简单性

  例如,你的代码中可能会出现以下情景

package sia.knights;

public class BraveKnight implements Knight {

    private Quest quest;
    private Minstrel minstrel;

    public BraveKnight(Quest quest, Minstrel minstrel) {
        this.quest = quest;
        this.minstrel = minstrel;
    }

    public void embarkOnQuest() {
        minstrel.singBeforeQuest();
        quest.embark();
        minstrel.singAfterQuest();
    }

}

  minstrel类可以看作一个日志功能,在某个其它类中,需要调用这个日志类来记录日志,导致这个功能代码与业务代码混淆在一起

  而Spring提供的AOP方案,可以通过配置文件等方式,将这个日志类的相关代码从这个业务类中去除,从而实现解耦;具体方式后面介绍

4、通过切面和模板减少样板式代码

  例如:以往使用JDBC进行操作数据库时,每次操作,都有很多连接数据库,断开连接等代码和业务代码交织在一齐

  而Spring则提供了如jdbcTemplate等类,对这些样板式代码进行简化

 

以上是关于为什么使用Spring的主要内容,如果未能解决你的问题,请参考以下文章

Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段

使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量