为什么我创建了一个轻量级迷你弹簧替代品以及我是如何做到的
2024-08-18 23:36:56
在这篇小文章中,我将试图解释为什么我创建了这个图书馆?以及它是如何实现的?
为什么要创建这个库?我在许多项目中使用它 Java EE 框架,大多数项目运行应用程序可用资源没有限制,但在极少数情况下,我们的资源有限,特别是部署应用程序内存的部署服务,所以当应用程序超过限制时,部署服务将首先减慢应用程序的速度,然后如果继续运行,服务将关闭。我们用传统的 Spring 甚至没有框架 Spring Boot,我们试图使用不同的库,但差异很小,毫无价值,这是为了创建一个轻量级 Spring 替代方案专注于尽可能减少内存消耗的想法的开始。 .
当我开始设计这个图书馆时,我脑子里只有两个目标: 1 - 尽量减少内存消耗 2 - 从学习的角度和过渡本身的复杂性来看,尽可能多地使用现有的 Java EE API,使向库的过渡变得容易。 凭借这两个目标,我成功地减少了其中一个应用程序的内存占用量 40% 因为它类似于现有的解决方案,所以左右过渡变得轻松快捷。
我是怎么创建这个库的?这里是 GitHub 在阅读时可以检查代码进行存储。
整个库有很多部分(截图如下),大部分实现在主模块中,主模块也分为三个独立模块:Core、JPA、Web。 App 模块主要用于集成,Plugin 模块是一个 Maven 插件,可以帮助在包装档案中创建必要的文件,使库正常工作
核心模块因此,顾名思义,我们将从核心模块开始,它包含库的核心功能,即依靠注入或控制逆转。 为了实现这一功能,首先在编译阶段扫描应用程序的类别路径,以查找库中应管理的所有带注释的类别,以定义带注释的类创建组件。
组件定义基本上包含了我们以后从此类实例对象所需的所有信息,比如构造函数信息。如果有一些带注入注释的setter(只支持构造函数和setter注入),如果有一些接口或扩展其他类别,我们将拥有从此类创建对象所需的所有信息(以下屏幕截图)。 然后,在扫描所有类型的路径注释并创建所需的所有组件定义后,我们将其视为 JSON 存储在类别路径中的文件。
核心模块的第二个主要功能是基于工厂设计模式的依赖注入和控制逆转。因此,我们有一个ApplicationContext接口,它扩展了CompontFactory接口。接口的主要方法是获取Compontext接口 该方法将从组件名称返回对象。
正如你在上面的屏幕截图中首先看到的,我们试图检查组件是否已初始化。 Singleton 如果组件不存在,那么我们首先从 JSON 在文件中获取组件定义,然后启动 while 在将组件定义及其依赖项传递给组件组装器以获得准备注入的完整对象之前,确定所有组件的依赖项。
JPA模块JPA 模块的实现与实现 spring data JPA 它非常相似,但很少。它非常相似的原因是我在许多项目中使用它 spring data,而且我发现它很容易使用,正如我之前所说,我希望过渡到仓库平稳,需要尽可能少的工作,从而实现我自己的迷你 Spring 数据版本是最佳选择。
实现围绕 JpaRepository 接口包括最常见的数据库操作,如保存、删除和删除 findAll..,为了使用 JPA 对于模块,您需要扩展该接口并提供该接口应管理的实体及其 id ,然后扩展界面并使用它 Repository 注解后,注解后,您可以定义方法并使用它 Query 注释注释并提供 JPQL 然后,库将在编译阶段创建一个功能齐全的类别,以实现接口。
图书馆还将管理应用程序的事务部分,因此从事务的角度来看,所有存储接口和任何带有事务注释的类别都将由图书馆管理。因此,对于任何事务组件,图书馆将创建一个基于管理的代理 Transactional 对实体管理器的生命周期进行注释和管理。
网页模块Web 模型负责管理所有的应用程序 Web 部分,根据设计,它是一个独立的模块,这意味着它可以独立于图书馆中的其他模块,通常用于一些熟悉的模块 Java EE非常相似 库,例如 Spring web 或 Jax-rs。
实现是基于注释的。您使用Controller注释的类别。在这个控制器中,您将找到使用PathMaping注释的方法。这些方法将根据某些标准(如类型类型)处理特定路径或特定请求和内容类型...
从外面看,它与其他图书馆非常相似,但从内部看,它是不同的,因为图书馆将在运行过程中更改这些图书馆类别,以扩展所有图书馆类别,这也扩展了图书馆类别 而且它们将被用作常规 servlet 工作。
如上图所示,首先我们在init方法中初始化组件,使用webaplicationcontext注入所有依赖项,然后我们将使用handlerquest方法处理所有传输到controller的请求,我们将使用现有的方法 servlet api 来管理控制器,这将有助于保持较低的内存占用,并减少成本,因为该库作为补充 servlet API 工作插件。
首先,我们试图将请求映射到正确的方法,然后我们试图从上下文或 HttpServletRequest 获取信息(如请求参数或标头或路径变量),将所有请求信息注入方法或请求文本...
我们转换所有这些信息,然后在请求时将它们注入到方法中作为参数,然后我们执行该方法并遵循它们 PathMapping 生成或内容类型(默认为 application/Json)然后我们将结果或结果转换为HttpServletResponse,然后将内容写入HttpServlet.
最后,如果在过程中出现问题并抛出错误,我们将捕获错误或异常,并尝试根据异常类型进行处理。我们有异常处理程序来处理不同类型的异常,用户可以提供更多的处理程序来处理他想要的任何异常。
Maven插件最后也是一个重要的部分 Maven 插件将创建应用程序的正常工作和构建 jar 或 war 包装所需的所有文件。 首先,插件搜索扫描路径和依赖项 component-definitions-json 它将从文件中生成文件:lazy-application.json:所有包含应用程序的组件及其依赖项lazy-application.properties:它包含控制器和实体的列表,因此在运行过程中不需要扫描类路径。 最后,如果包装是罐子,我们将得到主要类别。
最后,我们构建包存档文件,包括应用程序代码及其依赖项以及我们在上一步生成的文件。
为了让文章简短而不那么复杂地理解,我尽量不深入细节,当然代码可以在那里 GitHub 找到它,这样你就可以用它了。如果你有问题,请把它放在下面,我会尽力回答他们.
以上就是为什么我创建了一个轻量级迷你弹簧替代品以及我是如何做到的。请关注图灵教育的其他相关文章!