Skip to content

Spring的起源于J2EE密不可分,了解他们出现的历史,可以帮助我们更好的掌握Spring技术。

Java EE

什么是J2EE

❓问题1:什么是JAVA EE,他和JAVA语言本身,JAVA SE有什么关系呢? Java语言本身是一种编程语言,而Java SE、Java EE是Java平台的两个不同的版本,它们都基于Java语言。

  1. Java SE(Java Standard Edition):Java SE是Java平台的标准版,提供了Java语言的基本功能和核心API,包括面向对象编程、集合框架、输入输出、多线程等。
  2. Java EE(Java Enterprise Edition):Java EE是Java平台的企业版,建立在Java SE的基础之上,提供了一组扩展的API和工具,用于开发和部署大型、分布式、可扩展的企业级应用程序。Java EE包括了Java SE的全部功能,并提供了额外的企业级特性,例如Servlet、JSP、EJB、JPA、JMS等,以满足企业级应用程序开发的需求。

在实际开发中,Java EE应用程序通常运行在支持Java EE规范的应用服务器上,而Java SE则是Java EE的基础。 ❓问题2:使用JAVA SE,我只需要安装JDK,那我如何使用JAVA EE开发呢? 首先JAVA EE不是一个软件包,而是一组规范和API。我们可以导入J2EE相关库,在开发完成后,部署到支持 Java EE 标准的应用服务器上

java EE的起源

由于企业级应用需要处理的东西太多,包括网络、安全、数据库等等,1999年,SUN公司提出了一个想法:**容器****组件****的形式来提供服务,**容器负责共性的、底层的、复杂的内容,也为组件的运行提供环境,而组件负责具体的业务层面的内容。为了形成一个良好的JAVA开发生态,SUN公司还定义了一系列的规范,指定容器应该怎么做,组件应该怎么做。 容器是面向软件厂商,我们熟知的像tomcat就实现了J2EE容器规范,相应的还有jetty等等,而我们编写的程序,只要符合组件的规范,就可以跑在不同的容器上,这为程序的移植带来了极大的便利。

读一读这篇文章:IoC原理,介绍了为什么要使用IOC容器


最初的J2EE架构 J2EE出现的时候,正是WEB技术发展的时候,所以J2EE重点考虑如何为B/S架构的应用服务,基于MVC的思想,提出了EJB容器+Web容器,即业务逻辑层(M)+表示层(V)。

EJB容器与WEB容器有很多相同的地方,2002年10月份,Rod Johnson写了一本书《expert one to one J2EE Development without EJB》,基本思想是只使用Web容器而不使用EJB容器,并开发了一款在线订做应用,在这本书中,他使用了大量面向对象方法,实现了一个底层框架,在这个框架中第一次出现了依赖注入和AOP,这也是Spring Framework的起源(依赖注入和AOP与面向对象是息息相关的)。

image.png

java EE的发展简史

  • **J2EE(Java 2 Platform, Enterprise Edition),**J2EE 最早发布于1999年。它提供了一套标准的规范、API 和技术,用于开发企业级应用程序。
  • **Java EE(Java Enterprise Edition),**随着时间的推移,J2EE 迅速演化为 Java EE,该名称首次出现在 Java EE 5 中。Java EE 引入了新的功能、简化了开发模型,并保持了向后兼容性。
  • **Java EE 6,**该版本重点引入了 CDI(Contexts and Dependency Injection),并引入Servlet 3.0 规范,提供异步支持。
  • **Jakarta EE 8,**从 Oracle 转向 Eclipse Foundation,持续改进符合当今云原生应用开发的需求。

Spring

很多教程讲解Spring的时候,都会直接介绍Spring的两大核心IOC和AOP。作为初学者,看到这些概念都会一头雾水,学了半天也只知道了一些概念,似懂非懂。了解Spring的发展和Spring的设计理念对于我们掌握Spring是非常有帮助的。

Spring最早是由Rod Johnson在他的**《Expert One-on-One J2EE Development without EJB》**一书中提出的用来取代EJB的轻量级框架。随后这哥们又开始专心开发这个基础框架,并起名为**Spring Framework**

为什么需要IOC?

IOC是Spring中最重要的概念,IOC是一种设计原则,IoC 的起源可以追溯到面向对象技术的发展过程中。 我们先通过一个例子来看当没有IOC时,Java组件是如何协作的: 我们假定一个在线书店,通过BookService获取书籍:

java
public class BookService {
    private HikariConfig config = new HikariConfig();
    private DataSource dataSource = new HikariDataSource(config);

    public Book getBook(long bookId) {
        try (Connection conn = dataSource.getConnection()) {
            ...
            return book;
        }
    }
}

为了从数据库查询书籍,BookService持有一个DataSource。为了实例化一个HikariDataSource,又不得不实例化一个HikariConfig。 现在,我们继续编写UserService获取用户:

java
public class UserService {
    private HikariConfig config = new HikariConfig();
    private DataSource dataSource = new HikariDataSource(config);

    public User getUser(long userId) {
        try (Connection conn = dataSource.getConnection()) {
            ...
            return user;
        }
    }
}

因为UserService也需要访问数据库,因此,我们不得不也实例化一个HikariDataSource。 在处理用户购买的CartServlet中,我们需要实例化UserService和BookService:

java
public class CartServlet extends HttpServlet {
    private BookService bookService = new BookService();
    private UserService userService = new UserService();

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        long currentUserId = getFromCookie(req);
        User currentUser = userService.getUser(currentUserId);
        Book book = bookService.getBook(req.getParameter("bookId"));
        cartService.addToCart(currentUser, book);
        ...
    }
}

上述每个组件都采用了一种简单的通过new创建实例并持有的方式。仔细观察,会发现以下缺点:

  1. 实例化一个组件其实很难,例如,BookService和UserService要创建HikariDataSource,实际上需要读取配置,才能先实例化HikariConfig,再实例化HikariDataSource。
  2. 没有必要让BookService和UserService分别创建DataSource实例,完全可以共享同一个DataSource,但谁负责创建DataSource,谁负责获取其他组件已经创建的DataSource,不好处理。类似的,CartServlet和HistoryServlet也应当共享BookService实例和UserService实例,但也不好处理。
  3. **如何销毁组件?**很多组件需要销毁以便释放资源,例如DataSource,但如果该组件被多个组件共享,如何确保它的使用方都已经全部被销毁?
  4. 依赖关系复杂,代码编写难:随着更多的组件被引入,例如,书籍评论,需要共享的组件写起来会更困难,这些组件的依赖关系会越来越复杂。
  5. **难于测试:**测试某个组件,例如BookService,是复杂的,因为必须要在真实的数据库环境下执行。

💡从上面的例子可以看出,如果一个系统有大量的组件,其生命周期和相互之间的依赖关系如果由组件自身来维护,不但大大增加了系统的复杂度,而且会导致组件之间极为紧密的耦合,继而给测试和维护带来了极大的困难。

因此,核心问题是:

  1. 谁负责创建组件?
  2. 谁负责根据依赖关系组装组件?
  3. 销毁时,如何按依赖顺序正确销毁?

IOC的原理

传统的应用程序中,控制权在程序本身,程序的控制流程完全由开发者控制。在IoC模式下,控制权发生了反转,即从应用程序转移到了IoC容器,所有组件不再由应用程序自己创建和配置,而是由IoC容器负责,这样,应用程序只需要直接使用已经创建好并且配置好的组件。 因此,IoC又称为依赖注入(DI:Dependency Injection),它解决了一个最主要的问题:将组件的创建+配置与组件的使用相分离,并且,由IoC容器负责管理组件的生命周期。

Spring的发展

  1. Spring 1.0(2004年):
    • 由 Rod Johnson 在 Interface21 公司发布。
    • 提供了 IoC 容器、AOP(面向切面编程)、JDBC 抽象、事务管理等核心功能
  2. Spring 2.0(2006年):
    • 引入了新的功能,如注解驱动开发、更好的 AOP 支持和 AspectJ 集成。
    • 增强了对多种持久化技术的支持,例如 Hibernate、JPA 等。
    • Spring Web 模块也得到改进,提供了更好的 MVC 框架和 REST 支持。
  3. Spring 2.5(2007年):
    • 引入了注解驱动的依赖注入。
    • 提供了支持 JPA 的仓储库(Repository)模式。
    • 引入了 SpEL(Spring Expression Language)用于 Spring 表达式的解析。
  4. Spring 3.0(2009年):
    • 引入了基于 Java 5 的改进,如泛型依赖注入和注解。
    • 提供了 REST 支持、Java EE 6 支持、更好的对注解的支持等。
    • Spring 3.0 还提供了缓存抽象、任务执行器、TaskScheduler 等新特性。
  5. Spring 4.0(2014年):
    • 引入了对 Java 8 的支持。
    • 提供了对 Groovy 入口的支持。
    • 改进了 REST 支持,引入了 WebSocket、心跳检测等新特性。
  6. Spring 5.0(2017年):
    • 引入了对 Java 9 的支持。
    • 提供了响应式编程模型,引入了 WebFlux、Reactor 支持。
    • Spring 5.0 还改进了核心框架以及对 Java 8 的更好支持。
  7. Spring 5.1+
    • 后续版本继续改进和增强 Spring 框架,包括更好的 Kotlin 支持、对非阻塞 IO 的改进等。
    • 通过不断更新和改进,Spring 框架在持续地适应并采纳最新的 Java 技术趋势和最佳实践。

Spring的生态

Spring 生态系统是指围绕 Spring 框架构建的一系列项目、工具和技术,用于支持和扩展 Spring 框架的功能,以满足不同应用场景和需求。Spring 生态系统包括以下主要组成部分:

  1. Spring Framework:Spring 框架是整个生态系统的核心,提供了关键功能,如依赖注入、面向切面编程、事务管理等。它是构建企业级 Java 应用程序的基础。
  2. Spring Boot:Spring Boot 是 Spring 提供的快速开发框架,简化了 Spring 应用程序的构建和部署过程。它通过自动配置和约定大于配置的原则,使开发者能够更快地搭建 Spring 应用,并集成了嵌入式 Web 服务器等功能。
  3. Spring Cloud:Spring Cloud 是用于构建分布式系统的微服务架构工具包。它提供了诸如服务发现、负载均衡、断路器、分布式配置等功能,使开发者能够轻松构建和管理基于云的分布式系统。
  4. Spring Data:Spring Data 为数据访问和集成提供了一致性的编程模型。通过 Spring Data,开发者可以更方便地操作各种数据存储,包括关系型数据库、NoSQL 数据库等。
  5. Spring Security:Spring Security 专注于为应用程序提供安全性。它支持认证、授权、攻击防护等功能,帮助开发者保护应用程序中的敏感数据和功能。
  6. Spring Batch:Spring Batch 是 Spring 生态系统中用于批处理任务的框架。它提供了处理大规模数据批量任务的能力,如数据导入、转换、处理等。
  7. Spring Integration:Spring Integration 是用于构建企业集成解决方案的框架,支持消息驱动架构和 EAI(企业应用集成)模式。
  8. Spring HATEOAS:Spring HATEOAS (Hypermedia as the Enigne of Application State)是 Spring 的超媒体 API,用于构建 RESTful 服务,并支持超媒体驱动的方法来管理应用程序状态。
  9. Spring WebFlux:Spring WebFlux 提供了响应式编程模型,支持异步和非堵塞的并发,适用于构建高性能、低延迟的 Web 应用程序。