为何选择 Spring 做为 Java 框架

1. 概述

在本文中,咱们将讨论 Spring 做为最流行的 Java 框架之一的主要价值体现。html

最重要的是,咱们将尝试理解 Spring 成为咱们选择框架的缘由。Spring 的详细信息及其组成部分已在咱们 以前的教程中普遍介绍。 所以,咱们将跳过介绍性的“如何”部分,并主要关注“为何”。java

2. 为何使用任何框架?

在咱们开始任何关于 Spring 的讨论以前,首先让咱们了解为何咱们首先须要使用任何框架。react

像 Java 这样的通用编程语言可以支持多种应用程序。 更不用说 Java 天天都在积极地改进。web

此外,还有无数开源和专有库在这方面支持 Java 。spring

那么,咱们究竟为何须要一个框架呢?老实说,使用框架来完成任务并非绝对必要的。可是,出于如下几个缘由,使用一个一般是明智的:数据库

  • 帮助咱们专一于核心任务,而不是与之相关的样板
  • 以设计模式的形式聚集了多年的智慧
  • 帮助咱们遵照行业和监管标准
  • 下降应用程序的整体拥有成本

咱们刚刚触及了表面,咱们必须说,好处难以忽视。但这不多是积极的,因此要注意的是:编程

  • 强制咱们以特定的方式编写应用程序
  • 绑定到特定版本的语言和库
  • 添加到应用程序的资源占用

坦率地说,在软件开发和框架中没有什么银弹,Java 固然也不例外。所以,应该根据上下文来选择哪一个框架或不用框架。json

在本文的最后,咱们将更好地作出关于 Java 中的 Spring 的决策。设计模式

3. Spring 生态系统的简要概述

在咱们开始对 Spring 框架进行定性评估以前,让咱们仔细看看 Spring 生态系统是什么样子的。缓存

Spring 是在2003年的某个时候出现的,当时 Java 企业版发展迅速,开发企业应用程序很使人兴奋,但也很乏味!

Spring 最初是 Java 的 一个控制反转 (IoC)容器。咱们仍然主要将 Spring 与它联系起来,事实上,它构成了框架的核心,以及在此基础上开发的其余项目。

3.1. Spring 框架

Spring 框架 被划分为多个模块,这使得在任何应用程序中均可以很容易地选择要使用的部分:

  • Core:提供核心特性,如 DI (依赖注入)、国际化、验证和 AOP (面向切面编程)
  • Data Access:支持经过JTA ( Java事务 API )、JPA (Java 持久性 API )和 JDBC (Java 数据库链接)访问数据
  • Web:同时支持 Servlet API(Spring MVC)和最近的反应式 API(Spring WebFlux),另外还支持WebSockets、STOMP 和 WebClient
  • Integration:支持经过 JMS(Java 消息服务)、JMX (Java 管理扩展)和 RMI (远程方法调用)集成到企业 Java
  • Testing:经过模拟对象、测试装置、上下文管理和缓存支持单元和集成测试

3.2. Spring 项目

可是,Spring 更有价值的是一个强大的生态系统,这个生态系统多年来一直在发展,而且还在不断发展。 它们的结构是 Spring 项目 ,它们是在 Spring 框架之上开发的。

尽管 Spring 项目的清单很长,并且一直在变化,但仍有一些值得一提的地方:

  • Boot:为咱们提供了一组高度自定义但可扩展的模板,用于在几乎不花费时间的状况下建立基于 Spring 的各类项目。它使使用嵌入式 Tomcat 或相似容器建立独立的 Spring 应用程序变得很是容易。
  • Cloud:提供支持轻松地开发一些常见的分布式系统模式,如服务发现,断路器,以及 API 网关。 它有助于咱们减小在本地,远程甚至托管平台中部署此类样板模式的工做量。
  • Security:提供一种健壮的机制,以高度可定制的方式为基于 Spring 的项目开发身份验证和受权。经过最少的声明性支持,咱们能够得到对常见攻击的保护,好比会话固定、点击劫持和跨站点请求伪造。
  • Mobile:提供检测设备并相应地调整应用程序行为的功能。此外,支持设备感知的视图管理,以得到最佳用户体验、站点首选项管理和站点切换器。
  • Batch:提供轻量级框架,用于为数据归档等企业系统开发批处理应用程序。对调度、重启、跳过、收集指标和日志记录有直观的支持。此外,还支持经过优化和分区对大容量做业进行扩展。

毋庸置疑,这是对 Spring 所提供内容的一个至关抽象的介绍。可是它为咱们提供了关于 Spring 的组织和广度的足够的基础,以便咱们进一步讨论。

4. Spring 操做

人们习惯于添加一个 hello world 程序来了解任何新技术。

让咱们来看看 Spring 如何让编写一个不只仅是 Hello World 的程序变得轻松自如。咱们将建立一个应用程序,该应用程序将 CRUD 操做公开为一个域实体(如由内存数据库支持的雇员)的 REST API。更重要的是,咱们将使用基本认证来保护咱们的突变端点。最后,没有好的、旧的单元测试,任何应用程序都不能真正完成。

4.1. 项目设置

咱们将使用 Spring Initializr 设置 Spring Boot 项目,这是一个方便的在线工具,能够引导具备正确依赖项的项目。咱们将添加 Web、JPA、H2 和 Security 做为项目依赖项,以正确地得到 Maven 配置设置。 更多细节引导在咱们之前的文章之一。

4.2. 域模型和持久性

因为几乎不须要作什么,咱们已经准备好定义域模型和持久性。

让咱们首先将 Employee 定义为一个简单的 JPA 实体:

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
    // Standard constructor, getters and setters
}
复制代码

注意,咱们在实体定义中包含了自动生成的 id 。

如今咱们必须为实体定义 JPA 存储库。这就是 Spring 使它变得很是简单的地方:

public interface EmployeeRepository extends CrudRepository<Employee, Long> {
    List<Employee> findAll();
}
复制代码

咱们所要作的就是定义一个这样的接口,Spring JPA 将为咱们提供一个用默认和自定义操做充实的实现。至关整洁!在咱们的其余文章中能够找到更多关于 使用 Spring Data JPA 的细节。

4.3. 控制器

如今咱们必须定义一个网络控制器路由和处理咱们的传入请求:

@RestController
public class EmployeeController {
    @Autowired
    private EmployeeRepository repository;
    @GetMapping("/employees")
    public List<Employee> getEmployees() {
        return repository.findAll();
    }
    // Other CRUD endpoints handlers
}
复制代码

实际上,咱们所要作的就是对这个类使用注解并定义路由元信息以及每一个处理程序方法。

在咱们的前一篇文章中详细讨论了如何使用 Spring REST 控制器

4.4. 安全

因此如今咱们已经定义了全部内容,可是如何保护建立或删除员工之类的操做呢?咱们不但愿对这些端点进行未经身份验证的访问!

Spring Security 在这方面很是出色:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/employees", "/employees/**")
            .permitAll()
          .anyRequest()
            .authenticated()
          .and()
            .httpBasic();
    }
    // other necessary beans and definitions
}
复制代码

这里有 更多的细节须要注意理解 ,但最重要的一点是咱们只容许 GET 操做不受限制的声明式方式。

4.5. 测试

如今咱们已经作了全部的事情,可是等等,咱们如何测试这个呢?

让咱们看看 Spring 是否可让编写 REST 控制器的单元测试变得更容易:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class EmployeeControllerTests {
    @Autowired
    private MockMvc mvc;
    @Test
    @WithMockUser()
    public void givenNoEmployee_whenCreateEmployee_thenEmployeeCreated() throws Exception {
        mvc.perform(post("/employees").content(
            new ObjectMapper().writeValueAsString(new Employee("First", "Last"))
            .with(csrf()))
          .contentType(MediaType.APPLICATION_JSON)
          .accept(MediaType.APPLICATION_JSON))
          .andExpect(MockMvcResultMatchers.status()
            .isCreated())
          .andExpect(jsonPath("$.firstName", is("First")))
          .andExpect(jsonPath("$.lastName", is("Last")));
    }
    // other tests as necessary
}
复制代码

正如咱们所看到的,Spring 为咱们提供了必要的基础设施来编写简单的单元和集成测试,不然这些测试将依赖于要初始化和配置的 Spring 上下文。

4.6. 运行应用程序

最后,咱们如何运行这个应用程序?这是 Spring Boot 的另外一个有趣的方面。尽管咱们能够将其打包为常规应用程序并传统上部署在 Servlet 容器上。

但这有什么好玩的!Spring Boot 附带一个嵌入式 Tomcat 服务器

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
复制代码

这是一个预先建立的类,做为引导程序的一部分,具备使用嵌入式服务器启动此应用程序的全部必要细节。

此外,这是高度可定制的

5. Spring 的替代品

虽然选择使用框架相对容易,但在框架之间进行选择一般会让咱们的选择变得艰巨。 但为此,咱们必须至少粗略地了解 Spring 提供的功能有哪些替代方案。

如前所述,Spring 框架及其项目为企业开发人员提供了普遍的选择。若是咱们对当代 Java 框架作一个快速评估,它们甚至不能与 Spring 提供给咱们的生态系统相提并论。

然而,对于特定的领域,它们确实造成了一个使人信服的论据来选择替代方案:

  • Guice: 为 Java 应用程序提供一个健壮的 IoC 容器
  • Play: 很是适合做为具备响应性支持的 Web 框架
  • Hibernate: 一个基于 JPA 支持的数据访问框架

除了这些以外,还有一些新功能提供了比特定领域更普遍的支持,但仍然没有涵盖 Spring 必须提供的全部内容:

  • Micronaut: 一个基于 JVM 的框架,针对云本地微服务而定制
  • Quarkus: 一个新时代的 Java 栈,它承诺提供更快的启动时间和更小的内存占用

显然,彻底迭代这个列表既没必要要也不可行,可是咱们在这里获得了普遍的概念。

6. 为何选择 Spring?

最后,咱们构建了全部必需的上下文来解决咱们的核心问题,为何是 Spring?咱们了解框架能够帮助咱们开发复杂的企业应用程序的方式。

此外,咱们了解咱们针对特定问题所作的选择,例如 Web,数据访问,框架方面的集成,尤为是 Java 。

如今,在全部这些当中,Spring 的亮点在哪里?让咱们来探索一下。

6.1. 可用性

任何框架流行的一个关键方面是开发人员使用它是多么容易。Spring 经过多个配置选项和约定优于配置使开发人员能够轻松启动,而后准确配置他们须要的内容

Spring Boot 这样的项目使得引导一个复杂的 Spring 项目变得很是简单。更不用说,它有优秀的文档和教程来帮助任何人入门。

6.2. 模块化

Spring 受欢迎的另外一个关键方面是其高度模块化的特性。 咱们能够选择使用整个 Spring 框架或仅使用必要的模块。 此外,咱们能够根据须要选择包含一个或多个 Spring 项目。

并且,咱们还能够选择使用 Hibernate 或 Struts 等其余框架!

6.3. 一致性

虽然 Spring 不支持全部 Java EE 规范,但它支持全部技术,一般在必要时提升对标准规范的支持。 例如,Spring 支持基于 JPA 的存储库,所以切换提供程序变得微不足道。

此外,Spring 支持行业规范,如 Spring Web Reactive 下的 Reactive StreamSpring HATEOAS 下的 HATEOAS 。

6.4. 可测试性

采用任何框架在很大程度上还取决于测试构建在其上的应用程序是多么容易。 Spring 的核心是倡导并支持测试驱动开发(TDD)。

Spring 应用程序主要由 POJO 组成,这天然使单元测试相对简单得多。 可是,Spring 确实为 MVC 等场景提供了 Mock 对象,不然单元测试变得复杂。

6.5. 成熟

Spring 在创新、采用和标准化方面有着悠久的历史。多年来,它已经足够成熟,能够成为大型企业应用程序开发中最多见问题的默认解决方案

更使人兴奋的是积极的开发和维护。天天都在开发对新语言特性和企业集成解决方案的支持。

6.6. 社区支持

最后但并不是最不重要的是,任何框架甚至类库都经过创新在行业中生存下来,并且没有比社区更好的创新场所。 Spring 是由 Pivotal Software 领导的开源软件,由大型组织和我的开发者组成的支持。

这就意味着它仍然具备背景意义,并且每每具备将来主义色彩,这一点从它旗下项目的数量就能够明显看出。

7. 不使用 Spring 的缘由

有各类各样的应用程序能够从不一样级别的 Spring 使用中受益,而且这种应用程序的变化与 Spring 的增加速度同样快。

可是,咱们必须理解 Spring 和其余框架同样,有助于管理应用程序开发的复杂性。它帮助咱们避免常见的陷阱,并使应用程序随着时间的推移保持可维护性。

这是以额外的资源足迹和学习曲线为代价的,尽管可能很小。 若是确实存在一个足够简单而且预计不会变得复杂的应用程序,那么根本不使用任何框架可能会带来更多益处!

8. 结论

在本文中,咱们讨论了在应用程序开发中使用框架的好处。咱们还进一步简要的讨论了 Spring 框架。

在讨论这个主题时,咱们还研究了一些可用于 Java 的替代框架。

最后,咱们讨论了促使咱们选择 Spring 做为 Java 选择框架的缘由。

不过,咱们应该在本文的结尾给出一些建议。尽管听起来颇有说服力,但在软件开发中一般没有单一的、通用的解决方案

所以,咱们必须运用咱们的智慧,为咱们要解决的具体问题选择最简单的解决办法。


送福利啦~ 近期将以前已翻译文章,整理成PDF。

在公众号后台回复:002 便可领取哦~

后续也会不断更新PDF的内容,敬请期待!

img
相关文章
相关标签/搜索