Why Choose Spring as Your Java Framework? – 为什么选择Spring作为您的Java框架?

最后修改: 2019年 7月 4日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’ll go through the main value proposition of Spring as one of the most popular Java frameworks.

在本文中,我们将了解Spring作为最受欢迎的Java框架之一的主要价值主张。

More importantly, we’ll try to understand the reasons for Spring being our framework of choice. Details of Spring and its constituent parts have been widely covered in our previous tutorials. Hence we’ll skip the introductory “how” parts and mostly focus on “why”s.

更重要的是,我们将尝试了解Spring成为我们首选框架的原因。关于Spring及其构成部分的细节已经在我们之前的教程中广泛涉及。因此,我们将跳过介绍性的 “如何 “部分,而主要关注 “为什么 “的问题。

2. Why Use Any Framework?

2.为什么使用任何框架?

Before we begin any discussion in particular on Spring, let’s first understand why do we need to use any framework at all in the first place.

在我们开始特别讨论Spring之前,让我们先了解一下为什么我们首先需要使用任何框架。

A general purpose programming language like Java is capable of supporting a wide variety of applications. Not to mention that Java is actively being worked upon and improving every day.

像Java这样的通用编程语言能够支持各种各样的应用。更不用说,Java每天都在积极地工作和改进。

Moreover, there are countless open source and proprietary libraries to support Java in this regard.

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

So why do we need a framework after all? Honestly, it isn’t absolutely necessary to use a framework to accomplish a task. But, it’s often advisable to use one for several reasons:

那么,我们毕竟为什么需要一个框架呢?老实说,并不是绝对需要使用框架来完成一项任务。但是,出于几个原因,使用一个框架往往是明智的。

  • Helps us focus on the core task rather than the boilerplate associated with it
  • Brings together years of wisdom in the form of design patterns
  • Helps us adhere to the industry and regulatory standards
  • Brings down the total cost of ownership for the application

We’ve just scratched the surface here and we must say that the benefits are difficult to ignore. But it can’t be all positives, so what’s the catch:

我们在这里只是触及表面,我们必须说,其好处是难以忽视的。但它不可能都是积极的,所以有什么好处呢。

  • Forces us to write an application in a specific manner
  • Binds to a specific version of language and libraries
  • Adds to the resource footprint of the application

Frankly, there are no silver bullets in software development and frameworks are certainly no exception to that. So the choice of which framework or none should be driven from the context.

坦率地说,软件开发中没有银弹,框架当然也不例外。因此,选择哪种框架或不选择哪种框架,应该从实际情况出发。

Hopefully, we’ll be better placed to make this decision with respect to Spring in Java by the end of this article.

希望在本文结束时,我们能更好地对Java中的Spring做出这个决定。

3. Brief Overview of Spring Ecosystem

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

Before we begin our qualitative assessment of Spring Framework, let’s have a closer look into what does Spring ecosystem looks like.

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

Spring came into existence somewhere in 2003 at a time when Java Enterprise Edition was evolving fast and developing an enterprise application was exciting but nonetheless tedious!

Spring出现在2003年的某个地方,当时Java企业版正在快速发展,开发一个企业应用程序是令人兴奋的,但也是乏味的。

Spring started out as an Inversion of Control (IoC) container for Java. We still relate Spring mostly to it and in fact, it forms the core of the framework and other projects that have been developed on top of it.

Spring最初是作为Java的反转控制(IoC)容器。我们仍然主要将Spring与它联系在一起,事实上,它构成了该框架和其他在其之上开发的项目的核心。

3.1. Spring Framework

3.1.Spring框架

Spring framework is divided into modules which makes it really easy to pick and choose in parts to use in any application:

Spring框架被划分为多个模块,这使得它可以非常容易地在任何应用程序中挑选使用的部分。

  • Core: Provides core features like DI (Dependency Injection), Internationalisation, Validation, and AOP (Aspect Oriented Programming)
  • Data Access: Supports data access through JTA (Java Transaction API), JPA (Java Persistence API), and JDBC (Java Database Connectivity)
  • Web: Supports both Servlet API (Spring MVC) and of recently Reactive API (Spring WebFlux), and additionally supports WebSockets, STOMP, and WebClient
  • Integration: Supports integration to Enterprise Java through JMS (Java Message Service), JMX (Java Management Extension), and RMI (Remote Method Invocation)
  • Testing: Wide support for unit and integration testing through Mock Objects, Test Fixtures, Context Management, and Caching

3.2. Spring Projects

3.2.Spring项目

But what makes Spring much more valuable is a strong ecosystem that has grown around it over the years and that continues to evolve actively. These are structured as Spring projects which are developed on top of the Spring framework.

但是,使Spring更有价值的是多年来围绕它发展起来的强大的生态系统,并且该系统还在继续积极发展。这些项目的结构是Spring项目,它们是在Spring框架的基础上开发的。

Although the list of Spring projects is a long one and it keeps changing, there are a few worth mentioning:

尽管Spring项目的清单很长,而且不断变化,但有几个项目值得一提。

  • Boot: Provides us with a set of highly opinionated but extensible template for creating various projects based on Spring in almost no time. It makes it really easy to create standalone Spring applications with embedded Tomcat or a similar container.
  • Cloud: Provides support to easily develop some of the common distributed system patterns like service discovery, circuit breaker, and API gateway. It helps us cut down the effort to deploy such boilerplate patterns in local, remote or even managed platforms.
  • Security: Provides a robust mechanism to develop authentication and authorization for projects based on Spring in a highly customizable manner. With minimal declarative support, we get protection against common attacks like session fixation, click-jacking, and cross-site request forgery.
  • Mobile: Provides capabilities to detect the device and adapt the application behavior accordingly. Additionally, supports device-aware view management for optimal user experience, site preference management, and site switcher.
  • Batch: Provides a lightweight framework for developing batch applications for enterprise systems like data archival. Has intuitive support for scheduling, restart, skipping, collecting metrics, and logging. Additionally, supports scaling up for high-volume jobs through optimization and partitioning.

Needless to say that this is quite an abstract introduction to what Spring has to offer. But it provides us enough ground with respect to Spring’s organization and breadth to take our discussion further.

不用说,这是对Spring所提供的东西的一个相当抽象的介绍。但它在Spring的组织和广度方面为我们提供了足够的基础来进一步讨论。

4. Spring in Action

4.Spring在行动

It is customary to add a hello-world program to understand any new technology.

按照惯例,要了解任何新技术,都要添加一个hello-world程序。

Let’s see how Spring can make it a cakewalk to write a program which does more than just hello-world. We’ll create an application that will expose CRUD operations as REST APIs for a domain entity like Employee backed by an in-memory database. What’s more, we’ll protect our mutation endpoints using basic auth. Finally, no application can really be complete without good, old unit tests.

让我们看看Spring是如何使编写程序变得轻而易举的,而不仅仅是做hello-world。我们将创建一个应用程序,将CRUD操作作为REST API暴露给像Employee这样由内存数据库支持的领域实体。更重要的是,我们将使用基本认证来保护我们的突变端点。最后,如果没有良好的、古老的单元测试,任何应用程序都不可能真正完整。

4.1. Project Set-up

4.1.项目设置

We’ll set up our Spring Boot project using Spring Initializr, which is a convenient online tool to bootstrap projects with the right dependencies. We’ll add Web, JPA, H2, and Security as project dependencies to get the Maven configuration set-up correctly.

我们将使用Spring Initializr来设置我们的Spring Boot项目,这是一个方便的在线工具,可以用正确的依赖性来引导项目。我们将添加Web、JPA、H2和Security作为项目依赖,以正确设置Maven的配置。

More details on bootstrapping are available in one of our previous articles.

更多关于引导的细节可在我们之前的一篇文章中找到。

4.2. Domain Model and Persistence

4.2.领域模型和持久性

With so little to be done, we are already ready to define our domain model and persistence.

由于要做的事情太少,我们已经准备好定义我们的领域模型和持久性。

Let’s first define the Employee as a simple JPA entity:

让我们首先将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
}

Note the auto-generated id we’ve included in our entity definition.

注意我们在实体定义中包含的自动生成的ID。

Now we have to define a JPA repository for our entity. This is where Spring makes it really simple:

现在我们必须为我们的实体定义一个JPA存储库。这就是Spring让它变得非常简单的地方。

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

All we have to do is define an interface like this, and Spring JPA will provide us with an implementation fleshed out with default and custom operations. Quite neat! Find more details on working with Spring Data JPA in our other articles.

我们所要做的就是定义一个这样的接口,而Spring JPA将为我们提供一个充满默认和自定义操作的实现。相当整洁!请在我们的其他文章中查找有关使用 Spring Data JPA的更多细节。

4.3. Controller

4.3.控制器

Now we have to define a web controller to route and handle our incoming requests:

现在,我们必须定义一个网络控制器,以路由和处理我们的传入请求。

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

Really, all we had to do was annotate the class and define routing meta information along with each handler method.

实际上,我们所要做的就是注解类并与每个处理方法一起定义路由元信息

Working with Spring REST controllers is covered in great details in our previous article.

我们在之前的文章中详细介绍了使用Spring REST控制器的工作情况。

4.4. Security

4.4.安全问题

So we have defined everything now, but what about securing operations like create or delete employees? We don’t want unauthenticated access to those endpoints!

所以,我们现在已经定义了所有的东西,但是如何保证创建或删除员工等操作的安全呢?我们不希望未经认证的人访问这些端点。

Spring Security really shines in this area:

春秋彩票娱乐平台在这一领域确实大放异彩。

@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
}

There are more details here which require attention to understand but the most important point to note is the declarative manner in which we have only allowed GET operations unrestricted.

这里有更多的细节,需要注意理解,但最重要的一点是我们只允许GET操作不受限制的声明性方式

4.5. Testing

4.5.测试

Now we’ have done everything, but wait, how do we test this?

现在我们已经做了一切,但等等,我们如何测试这个?

Let’s see if Spring can make it easy to write unit tests for REST controllers:

让我们看看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
}

As we can see, Spring provides us with the necessary infrastructure to write simple unit and integration tests which otherwise depend on the Spring context to be initialized and configured.

正如我们所看到的,Spring为我们提供了必要的基础设施来编写简单的单元和集成测试,否则就需要依赖Spring上下文来进行初始化和配置。

4.6. Running the Application

4.6.运行应用程序

Finally, how do we run this application? This is another interesting aspect of Spring Boot. Although we can package this as a regular application and deploy traditionally on a Servlet container.

最后,我们如何运行这个应用程序?这是Spring Boot的另一个有趣的方面。虽然我们可以把它打包成一个普通的应用程序,并在Servlet容器上进行传统的部署。

But where is fun this that! Spring Boot comes with an embedded Tomcat server:

但这哪里是有趣的事!?Spring Boot带有一个嵌入式Tomcat服务器

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

This is a class which comes pre-created as part of the bootstrap and has all the necessary details to start this application using the embedded server.

这是一个预先创建的类,作为bootstrap的一部分,它拥有使用嵌入式服务器启动该应用程序的所有必要细节。

Moreover, this is highly customizable.

此外,这是可高度定制的

5. Alternatives to Spring

5.Spring的替代品

While choosing to use a framework is relatively easier, choosing between frameworks can often be daunting with the choices we have. But for that, we must have at least a rough understanding of what alternatives are there for the features that Spring has to offer.

虽然选择使用一个框架相对来说比较容易,但在框架之间的选择往往会让我们望而生畏,因为我们有很多选择。但为此,我们至少要对Spring所提供的功能有哪些替代方案有一个大致的了解。

As we discussed previously, the Spring framework together with its projects offer a wide choice for an enterprise developer to pick from. If we do a quick assessment of contemporary Java frameworks, they don’t even come close to the ecosystem that Spring provides us.

正如我们之前讨论的,Spring框架及其项目为企业开发者提供了广泛的选择。如果我们对当代的Java框架做一个快速的评估,它们甚至不能接近Spring为我们提供的生态系统。

However, for specific areas, they do form a compelling argument to pick as alternatives:

然而,对于特定的领域,它们确实形成了一个令人信服的论点,可以作为替代方案来挑选。

  • Guice: Offers a robust IoC container for Java applications
  • Play: Quite aptly fits in as a Web framework with reactive support
  • Hibernate: An established framework for data access with JPA support

Other than these there are some recent additions that offer wider support than a specific domain but still do not cover everything that Spring has to offer:

除此以外,还有一些最近增加的功能,提供比特定领域更广泛的支持,但仍然没有涵盖Spring所能提供的一切。

  • Micronaut: A JVM-based framework tailored towards cloud-native microservices
  • Quarkus: A new age Java stack which promises to deliver faster boot time and a smaller footprint

Obviously, it’s neither necessary nor feasible to iterate over the list completely but we do get the broad idea here.

显然,完全迭代列表既无必要也不可行,但我们在这里确实得到了大致的概念。

6. So, Why Choose Spring?

6.那么,为什么选择Spring?

Finally, we’ve built all the required context to address our central question, why Spring? We understand the ways a framework can help us in developing complex enterprise applications.

最后,我们已经建立了所有必要的背景,以解决我们的中心问题,即为什么是Spring?我们了解了一个框架可以帮助我们开发复杂的企业应用的方式。

Moreover, we do understand the options we’ve got for specific concerns like web, data access, integration in terms of framework, especially for Java.

此外,我们确实了解我们在特定的关注点上的选择,如网络、数据访问、框架方面的整合,特别是对于Java。

Now, where does Spring shine among all these? Let’s explore.

现在,在所有这些中,Spring在哪里闪耀?让我们来探讨一下。

6.1. Usability

6.1.可用性

One of the key aspects of any framework’s popularity is how easy it is for developers to use it. Spring through multiple configuration options and Convention over Configuration makes it really easy for developers to start and then configure exactly what they need.

任何框架受欢迎的一个关键方面是它对开发者来说是多么容易使用。Spring通过多种配置选项和Convention over Configuration,使开发人员能够非常容易地开始,然后准确地配置他们需要的东西。

Projects like Spring Boot have made bootstrapping a complex Spring project almost trivial. Not to mention, it has excellent documentation and tutorials to help anyone get on-boarded.

Spring Boot这样的项目使启动一个复杂的Spring项目几乎变得微不足道。更不用说,它有优秀的文档和教程,可以帮助任何人上手。

6.2. Modularity

6.2.模块化

Another key aspect of Spring’s popularity is its highly modular nature. We’ve options to use the entire Spring framework or just the modules necessary. Moreover, we can optionally include one or more Spring projects depending upon the need.

Spring受欢迎的另一个关键方面是它的高度模块化性质。我们可以选择使用整个Spring框架或只使用必要的模块。此外,我们可以根据需要选择包括一个或多个Spring项目

What’s more, we’ve got the option to use other frameworks like Hibernate or Struts as well!

更重要的是,我们还可以选择使用其他框架,如Hibernate或Struts!

6.3. Conformance

6.3.一致性

Although Spring does not support all of Jakarta EE specifications, it supports all of its technologies, often improving the support over the standard specification where necessary. For instance, Spring supports JPA based repositories and hence makes it trivial to switch providers.

虽然Spring不支持Jakarta EE的所有规范,但它支持其所有的技术,在必要时往往比标准规范改进支持。例如,Spring支持基于JPA的存储库,从而使切换供应商变得非常简单。

Moreover, Spring supports industry specifications like Reactive Stream under Spring Web Reactive and HATEOAS under Spring HATEOAS.

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

6.4. Testability

6.4.可测试性

Adoption of any framework largely also depends on the fact that how easy it is to test the application built on top of it. Spring at the core advocates and supports Test Driven Development (TDD).

任何框架的采用在很大程度上也取决于对建立在其上的应用程序进行测试的容易程度。Spring的核心是倡导和支持测试驱动开发(TDD)。

Spring application is mostly composed of POJOs which naturally makes unit testing relatively much simpler. However, Spring does provide Mock Objects for scenarios like MVC where unit testing gets complicated otherwise.

Spring应用程序大多由POJOs组成,这自然使单元测试相对简单得多。然而,Spring确实为MVC等场景提供了Mock对象,否则单元测试会变得很复杂。

6.5. Maturity

6.5 成熟度

Spring has a long history of innovation, adoption, and standardization. Over the years, it’s become mature enough to become a default solution for most common problems faced in the development of large scale enterprise applications.

Spring有着悠久的创新、采用和标准化的历史。多年来,它已经变得成熟,足以成为大型企业应用开发中面临的大多数常见问题的默认解决方案

What’s even more exciting is how actively it’s being developed and maintained. Support for new language features and enterprise integration solutions are being developed every day.

更令人兴奋的是,它的开发和维护是如此积极。对新的语言功能和企业集成解决方案的支持每天都在发展。

6.6. Community Support

6.6.社区支持

Last but not least, any framework or even library survive the industry through innovation and there’s no better place for innovation than the community. Spring is an open source led by Pivotal Software and backed by a large consortium of organizations and individual developers.

最后但并非最不重要的是,任何框架甚至库都是通过创新在行业中生存,而没有比社区更好的创新场所了。Spring是一个开放源码,由Pivotal软件公司领导,并由一个大型的组织和个人开发者联盟支持

This has meant that it remains contextual and often futuristic, as evident by the number of projects under its umbrella.

这意味着它仍然具有背景性,而且往往具有未来性,这一点从其旗下的项目数量就可以看出。

7. Reasons Not to Use Spring

7.不使用Spring的原因不是

There is a wide variety of application which can benefit from a different level of Spring usage, and that is changing as fast as Spring is growing.

有各种各样的应用可以从不同程度的Spring使用中受益,而且这种情况正像Spring的发展一样快速变化。

However, we must understand that Spring like any other framework is helpful in managing the complexity of application development. It helps us to avoid common pitfalls and keeps the application maintainable as it grows over time.

然而,我们必须明白,Spring和其他框架一样,有助于管理应用开发的复杂性。它可以帮助我们避免常见的陷阱,并在应用程序随时间增长时保持其可维护性。

This comes at the cost of an additional resource footprint and learning curve, however small that may be. If there is really an application which is simple enough and not expected to grow complex, perhaps it may benefit more to not use any framework at all!

是以额外的资源占用和学习曲线为代价的,不管这可能有多小。如果真的有一个足够简单的应用程序,并且没有预期会变得复杂,也许根本不使用任何框架会更有好处。

8. Conclusion

8.结语

In this article, we discussed the benefits of using a framework in application development. We further discussed briefly Spring Framework in particular.

在这篇文章中,我们讨论了在应用开发中使用框架的好处。我们进一步简要地讨论了Spring框架。

While on the subject, we also looked into some of the alternate frameworks available for Java.

在这个问题上,我们还研究了一些可用于Java的替代框架。

Finally, we discussed the reasons which can compel us to choose Spring as the framework of choice for Java.

最后,我们讨论了可以迫使我们选择Spring作为Java的首选框架的原因。

We should end this article with a note of advice, though. However compelling it may sound, there is usually no single, one-size-fits-all solution in software development.

不过,我们应该以一个建议来结束这篇文章。无论听起来多么引人注目,在软件开发中通常没有单一的、适合所有人的解决方案

Hence, we must apply our wisdom in selecting the simplest of solutions for the specific problems we target to solve.

因此,我们必须运用我们的智慧,为我们所要解决的具体问题选择最简单的解决方案。