JHipster安装和介绍

JHipster 是一个开发平台,可以快速生成,开发和部署现代 Web 应用程序+微服务架构。 JHipster 或者称 Java Hipster,是一个应用代码产生器,能够创建 Spring Boot/Spring Cloud + React/VueJs/AngularJS 的应用。使用 JHipster,首先你要配置好 Java 、Git 以及 Maven 或者 Gradle 的环境,然后通过 NodeJs 管理工具安装 JHipster 。 介绍 JHipster 官网: https://www.jhipster.tech/ ,截止本文发布时,最新版本为 8.0.0 。 JHipster 客户端使用到的技术栈有: 服务端使用的技术栈有: 支持以下部署方式: JHipster 提供了一个 CLI 工具 generator-jhipster 和在线网站 https://start.jhipster.tech/ ,来创建应用。generator-jhipster 支持本地安装和 docker 安装两种方式。另外,还有一个轻量级的定制工具 jhipseter-lite 可以更细力度的定制。 JHipster Pro 是一个 JHipster 国内落地方案,符合国情的代码生成器解决方案,支持 MyBatis、SMS、OSS。当前最新版本对应 JHipster 官方版本:v7.1.0,网站最近一次跟新是在 2021 年 8 月份。 安装 generator-jhipster 前提条件安装 Java 和 NodeJs,然后通过 npm 或者 yarn 安装 generator-jhipster。以下是通过 npm 安装: npm install -g generator-jhipster 查看版本: $ npx jhipster --version 8.0.0-rc.1 另外,可以在 docker 里面安装: docker image pull jhipster/jhipster docker container run --name jhipster -v ~/jhipster:/home/jhipster/app -v ~/....

Java设计模式:Circuit Breaker

本文主要介绍 Circuit Breaker 断路器模式,在 Java Design Patterns 网站上有对该模式进行介绍。这里主要是做个笔记,并添加一些扩展,以加深对该设计模式的理解。 介绍 断路器模式(Circuit Breaker Pattern)是一种在分布式系统中处理故障和提高系统可靠性的设计模式。它的主要目标是防止故障的传递,并在故障发生时提供优雅的故障处理机制。 在一个分布式系统中,不可避免地会出现许多外部依赖,如数据库、网络服务等。这些外部依赖可能会发生故障、延迟或不可用的情况。如果没有适当的措施,这些故障可能会导致整个系统的性能下降,甚至系统崩溃。 断路器模式通过在应用程序和外部依赖之间引入一个断路器接口来解决这个问题。断路器接口充当一个中间层,监视对外部依赖的调用。当外部依赖发生故障时,断路器可以迅速地中断对外部依赖的调用,避免资源的浪费和故障的传递。 除了断路器接口之外,断路器模式还涉及以下几个重要的知识点: 故障阈值(Failure Threshold):断路器模式通过设置故障阈值来判断服务的健康状态。当服务的失败次数达到或超过故障阈值时,断路器会打开,阻止对服务的进一步调用。 回退响应(Fallback Response):当断路器打开时,可以为调用方提供回退响应。回退响应是一个预定义的响应,用于代替无法正常调用的服务的响应。回退响应可以是事先定义好的静态响应,或者是通过调用备用服务来获取的响应。 断路器状态(Circuit Breaker State):断路器可以处于不同的状态,如关闭(Closed)、打开(Open)和半开(Half-Open)。初始状态通常是关闭状态,表示服务正常可用。当服务的失败次数达到故障阈值时,断路器会打开,阻止对服务的进一步调用。在一定时间后,断路器会进入半开状态,允许发起一次测试调用。如果测试调用成功,断路器将重新关闭;如果测试调用仍然失败,断路器将重新打开。 断路器的自动恢复(Automatic Recovery):断路器模式通常具有自动恢复功能。在断路器打开的状态下,一段时间过去后,断路器会尝试重新关闭,以允许对服务的正常调用。自动恢复可以防止长时间的服务中断,提供给服务一个机会来恢复正常运行。 健康检查(Health Check):断路器模式可以通过定期的健康检查来监控服务的状态。健康检查可以是定期发送心跳请求或执行一些特定的健康检查操作。通过健康检查,可以及时发现服务的故障或不可用状态,并相应地打开断路器。 示例 首先,您需要创建一个监控服务类,它将使用断路器来包装远程服务的调用。以下是一个示例监控服务类的代码: public class MonitoringService { private final CircuitBreaker delayedService; private final CircuitBreaker quickService; public MonitoringService(CircuitBreaker delayedService, CircuitBreaker quickService) { this.delayedService = delayedService; this.quickService = quickService; } public String localResourceResponse() { return "Local Service is working"; } public String delayedServiceResponse() { try { return this.delayedService.attemptRequest(); } catch (RemoteServiceException e) { return e.getMessage(); } } public String quickServiceResponse() { try { return this.quickService.attemptRequest(); } catch (RemoteServiceException e) { return e.getMessage(); } } } 在上述代码中,MonitoringService 类接受两个断路器对象作为参数,分别用于包装延迟服务和快速服务的远程调用。它还包含一个用于获取本地资源的方法。...

2023-10-26 5 min

Java设计模式:Chain

本文主要介绍 Chain 模式,在 Java Design Patterns 网站上有对该模式进行介绍。这里主要是做个笔记,并添加一些扩展,以加深对该设计模式的理解。 目的 通过给多个对象一个处理请求的机会,避免请求的发送者和它的接收者耦合。串联接收对象并在链条中传递请求直到一个对象处理它。 介绍 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照顺序处理请求,直到其中一个对象能够处理该请求为止。该模式将请求发送者和接收者解耦,使多个对象都有机会处理请求,同时避免请求发送者与接收者之间的直接耦合。 在责任链模式中,通常会构建一个处理请求的链条,链条上的每个对象都有一个指向下一个对象的引用。当请求到达链条的起点时,它会依次经过链条上的每个对象,直到找到能够处理请求的对象为止。每个对象都可以决定是否处理请求,或者将请求传递给下一个对象。 以下是责任链模式的几个关键角色: 抽象处理器(Handler):定义处理请求的接口,并包含一个指向下一个处理器的引用。通常会提供一个处理请求的方法。 具体处理器(ConcreteHandler):实现抽象处理器的接口,具体处理请求的逻辑。如果自己无法处理请求,则将请求传递给下一个处理器。 客户端(Client):创建责任链,并将请求发送给链条的起点。 下面是一个示例,说明如何使用责任链模式处理请求: // 抽象处理器 public abstract class Handler { protected Handler nextHandler; public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; } public abstract void handleRequest(Request request); } // 具体处理器 public class ConcreteHandler1 extends Handler { @Override public void handleRequest(Request request) { if (满足处理条件) { // 处理请求的逻辑 } else if (nextHandler != null) { // 将请求传递给下一个处理器 nextHandler.handleRequest(request); } } } // 具体处理器2和具体处理器3的定义与具体处理器1类似 // 客户端 public class Client { public static void main(String[] args) { Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); // 构建责任链 handler1....

2023-10-16 2 min

Java设计模式:Callback

本文主要介绍 Callback 模式,在 Java Design Patterns 网站上有对该模式进行介绍。这里主要是做个笔记,并添加一些扩展,以加深对该设计模式的理解。 介绍 回调(Callback)是一种设计模式,在这种模式中,一个可执行的代码被作为参数传递给其他代码,接收方的代码可以在适当的时候调用它。 在真实世界的例子中,当我们需要在任务完成时被通知时,我们可以将一个回调方法传递给调用者,并等待它调用以通知我们。简单地说,回调是一个传递给调用者的方法,在定义的时刻被调用。 维基百科说 在计算机编程中,回调又被称为“稍后调用”函数,可以是任何可执行的代码用来作为参数传递给其他代码;其它代码被期望在给定时间内调用回调方法。 代码 回调是一个只有一个方法的简单接口。 public interface Callback { void call(); } 下面我们定义一个任务它将在任务执行完成后执行回调。 public abstract class Task { final void executeWith(Callback callback) { execute(); Optional.ofNullable(callback).ifPresent(Callback::call); } public abstract void execute(); } public final class SimpleTask extends Task { private static final Logger LOGGER = getLogger(SimpleTask.class); @Override public void execute() { LOGGER.info("Perform some important activity and after call the callback method."); } } 最后这里是我们如何执行一个任务然后接收一个回调当它完成时。 var task = new SimpleTask(); task.executeWith(() -> LOGGER.info("I'm done now.")); 类图 适用场景 回调模式适用于以下场景: 异步操作:当需要在异步操作完成后执行某些操作时,可以使用回调模式。例如,在网络请求中,可以传递一个回调函数,在请求完成后调用该函数处理响应数据。 事件处理:当需要对事件进行响应和处理时,可以使用回调模式。例如,在图形界面开发中,可以注册某个控件的回调函数,以便在用户触发事件时执行相应的操作。 插件扩展:当需要为应用程序提供扩展性,允许第三方插件在特定事件发生时进行自定义操作时,可以使用回调模式。例如,游戏引擎中的事件系统允许开发者注册回调函数以响应游戏中的特定事件。 回调链:当需要按特定顺序执行多个回调函数,并将前一个回调函数的结果传递给下一个回调函数时,可以使用回调模式。这种情况下,回调函数形成了一个回调链。 模板方法模式:回调模式常与模板方法模式结合使用。模板方法模式定义了一个算法的骨架,而具体的步骤由子类实现。可以使用回调模式将子类中的具体步骤作为回调函数传递给模板方法。 总的来说,回调模式适用于需要在特定事件发生后执行某些操作的情况,以及需要实现解耦和灵活性的场景。它提供了一种在代码间通信的方式,使得代码可以更加模块化和可复用。 Java 例子 CyclicBarrier 构造函数可以接受回调,该回调将在每次障碍被触发时触发。 FAQ 回调模式如何实现解耦和灵活性? 回调模式通过将一个可执行的代码块(回调函数)作为参数传递给其他代码,实现了解耦和灵活性。 解耦性:回调模式可以将调用方与被调用方解耦,使它们之间的关系更加松散。调用方只需要知道回调函数的接口,而不需要了解具体的实现细节。被调用方在特定的时机调用回调函数,而不需要知道调用方的具体实现。这种解耦性使得系统中的不同部分可以独立地进行修改和扩展,而不会对彼此产生过多的依赖。 灵活性:回调模式提供了一种灵活的扩展机制。通过传递不同的回调函数,可以改变程序的行为或逻辑,而不需要修改原有的代码。这种灵活性使得系统可以适应不同的需求和变化,而不需要进行大规模的修改或重构。同时,回调模式也允许在运行时动态地修改回调函数,从而实现更高级的动态行为。...

2023-10-13 2 min

[译]Spring Boot3和Spring6中的新特性

Spring Boot 3.0 于 2022 年 11 月正式发布,包含一些新功能和改进。这是继大约 4.5 年前发布 Spring Boot 2.0 后 Spring Boot 的第一个主要版本。它也是第一个支持 Spring Framework 6.0 的 Spring Boot GA 版本。作为开发人员,我们需要了解这些更新,才能顺利使用 Spring Boot。毫无疑问,新版本中最大的转变之一是放弃了对旧版本 Java 的支持。 在本文中,我们将讨论“Spring Boot 3 和 Spring 6 中的新功能”。 Spring 3.0 版本有哪些主要亮点? Spring 3.0 版本的亮点包括: Java 17 基线 支持 Jakarta EE 10 和 EE 9 基线 支持使用 GraalVM 生成本机映像,取代实验性 Spring Native 项目 通过测微计和测微计追踪提高了可观测性 谁可以真正使用 Spring Boot 3? 如前所述,Spring Boot 3.0 最大的转变是忽略了对旧版本 Java 的支持。是的,我们至少需要 Java 17 才能使用 Spring Boot 3.0。因此,在使用 Spring Boot 3.0 之前必须具备 JDK 17 环境。 Spring Boot 3 和 Spring 6 有哪些新功能? 这里需要注意的重要一点是 Spring Boot 3.0 构建于 Spring Framework 6 之上并需要 Spring Framework 6。因此,如果您的 pom....

[译]Spring Security 面试问题

本面试准备指南将讨论一些常见的 Spring Security 面试问题。无论您是准备面试还是只是想增强对 Spring Security 的了解,这些问题都将帮助您理解关键概念并指导您设计常见安全问题的解决方案。 1. Spring Security 的核心特性是什么? Spring Security 提供的两个最突出的功能是身份验证和授权。这些功能在确保应用程序的安全性方面发挥着至关重要的作用。然而,Spring Security 超越了身份验证和授权,还提供了额外的功能来防止漏洞利用并与其他框架集成。 1.1.验证 身份验证是验证尝试访问应用程序的用户身份的过程。 Spring Security 提供多种身份验证方法(基于表单的身份验证、HTTP 基本身份验证、OAuth2、Siteminder、OpenID Connect、LDAP、JDBC 等),允许应用程序使用各种方法对用户进行身份验证。 它还支持自定义,当默认选项不满足要求时,可以实现自定义的身份验证机制。 1.2.授权 授权是向经过身份验证的用户或实体授予许可或权利的过程。用户或实体成功通过身份验证后,授权将决定他们可以在应用程序中访问哪些操作或资源。 Spring Security 为开发人员提供了多种方法来实现授权并控制用户对应用程序不同部分的访问。以下是一些常见的方法: 基于 Web URL 的授权:可以根据特定的 URL 或 URL 模式实施访问控制,规范哪些用户可以访问某些资源。 方法级授权:如果需要,甚至可以对 Java Bean 中的方法进行访问控制,从而在方法级提供细粒度的授权。 域实例级授权:Spring Security 提供了控制对特定域实例的访问的能力,允许基于某些实体的所有权或关联进行授权。 1.3.防止漏洞利用 Spring Security 提供了多种功能来防范常见的 Web 应用程序安全漏洞。一些显着的功能包括: 跨站请求伪造 (CSRF) 保护:Spring Security 会自动将 CSRF 令牌添加到表单和 AJAX 请求中,从而防止 CSRF 攻击。 跨站脚本 (XSS) 保护:Spring Security 支持输出编码,并提供实用程序通过清理用户输入来防止 XSS 攻击。 点击劫持保护:Spring Security 包括 X-Frame-Options 支持,以防止点击劫持攻击。 1.4.集成 Spring Security 与其他框架和库无缝集成,以增强应用程序的安全性。一些关键的集成是: Spring MVC:Spring Security 与 Spring MVC 集成,为 Web 应用程序提供无缝的安全功能。它可以安全地处理请求、身份验证、授权并防止常见的 Web 漏洞。 Spring Data:Spring Security 与 Spring Data 集成,以便在查询中引用当前用户。这种集成确保可以根据身份验证和授权规则轻松访问和过滤用户特定的数据。 Jackson:Jackson 的支持可以实现 Spring Security 相关类的高效序列化和反序列化,特别是在使用分布式会话或 Spring Session 等框架时,从而提高效率和可扩展性。 密码学:Spring Security 与各种密码库和算法集成,以提供敏感信息的安全存储和传输。这种集成包括密码散列、加密和安全通信协议等功能,以保护数据的机密性和完整性。 有关 Spring Security 功能的更详细信息,请参阅官方文档。...

Java设计模式:Caching

本文主要介绍 Caching 模式,在 Java Design Patterns 网站上有对该模式进行介绍。这里主要是做个笔记,并添加一些扩展,以加深对该设计模式的理解。 介绍 缓存模式(Caching Pattern)是一种设计模式,旨在通过在资源使用后将其保留在某个快速访问的存储中,并在需要时重新使用资源,以避免昂贵的资源重新获取。 缓存模式的目的是减少重复获取、初始化和释放同一资源所带来的不必要性能开销。通过将资源保留在缓存中,可以避免再次获取资源,从而提高系统的响应速度和性能。 在缓存模式中,当需要访问资源时,首先检查缓存中是否存在该资源的副本。如果缓存中存在资源,则直接从缓存中获取并返回给调用方。如果缓存中不存在资源,则需要从原始数据源或其他途径获取资源,并将其存储在缓存中,以供后续使用。 缓存模式适用于那些需要频繁访问、计算成本较高的资源的情况,例如数据库查询、网络请求、文件读写等。通过使用缓存模式,可以显著提升系统的性能和响应速度,减少对原始数据源的访问次数,从而降低系统的负载。 关于缓存模式的更多信息和实现方式,您可以参考以下资源: Write-Through, Write-Around, Write-Back: Cache Explained:对缓存模式进行了详细解释和说明,提供了不同的缓存策略和实现方式。 Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching:介绍了不同类型的缓存操作和策略,包括读取、写入、刷新等。 Cache-Aside Pattern:介绍了缓存模式中的一种常见实现方式,即"Cache-Aside"模式,包括其工作原理和使用方法。 实现策略 缓存模式有多种常见的实现策略,以下是其中一些常见的实现策略: 写入穿透(Write-Through):当从数据源获取数据时,将数据同时写入缓存。这样,在下一次需要相同数据时,可以从缓存中获取,避免再次访问数据源。写入穿透策略确保缓存中始终保持最新的数据。 写入回写(Write-Back):在数据发生变化时,首先将数据写入缓存,然后再定期将缓存中的数据批量写回到数据源。写入回写策略可以减少对数据源的频繁写入操作,提高性能。 写入旁路(Write-Around):将写操作直接发送到数据源,而不是通过缓存。这样可以避免将不经常访问的数据写入缓存,从而节省缓存空间。只有当数据被读取时,才会将其放入缓存。 刷新预取(Refresh-Ahead):在缓存中存储数据的同时,预先获取和更新与当前数据相关的其他数据。这样,当需要访问相关数据时,可以直接从缓存中获取,减少等待时间。 最近最少使用(Least Recently Used, LRU):根据数据的访问频率和时间进行缓存淘汰。当缓存空间不足时,优先淘汰最近最少被访问的数据,以保留最常用的数据。 固定时间过期(Time-To-Live, TTL):为缓存中的每个数据项设置一个固定的过期时间。一旦数据项超过过期时间,将被视为过期并从缓存中移除。 异步刷新(Asynchronous Refresh):在数据过期或无效时,通过异步方式从数据源获取新数据并更新缓存。这样可以避免阻塞调用方,提高系统的响应速度。 缓存框架 当涉及到缓存框架或工具时,有几个常见且广泛使用的选项可以考虑。以下是其中一些常见的缓存框架或工具: Ehcache: Ehcache 是一个流行的开源 Java 缓存框架,提供了各种缓存策略和功能,包括内存缓存、磁盘缓存、分布式缓存等。它易于使用且性能优秀,可以轻松集成到 Java 应用程序中。 Redis: Redis 是一个开源的高性能内存数据结构存储系统,也可以用作缓存。它支持多种数据结构和丰富的缓存功能,如数据过期、持久化、分布式缓存等。Redis 可以作为独立的缓存服务器,也可以与应用程序集成使用。 Memcached: Memcached 是一个简单而高效的分布式内存对象缓存系统。它以键值对的形式存储数据,并提供了分布式缓存的支持。Memcached 适用于高并发环境下的缓存需求,可以减轻后端数据库的压力。 Caffeine: Caffeine 是一个基于 Java 的高性能缓存库,专注于提供快速的缓存访问和高效的内存管理。它支持各种缓存策略和功能,并提供了线程安全和异步加载等特性。 Hazelcast: Hazelcast 是一个开源的分布式数据存储和计算平台,其中包括了分布式缓存的功能。它提供了高可用性和可扩展性,并支持多种缓存策略和分布式缓存模式。 Guava Cache: Guava Cache 是 Google 的 Guava 库中提供的一个本地缓存实现。它提供了简单易用的 API,支持各种缓存策略和功能,如过期时间、最大缓存大小、缓存统计等。 Apache Ignite: Apache Ignite 是一个内存计算平台,提供了分布式缓存和计算能力。它可以作为一个分布式缓存存储数据,并支持 SQL 查询、分布式计算、流处理等功能。 Couchbase: Couchbase 是一个面向企业应用的 NoSQL 数据库和缓存平台。它提供了可扩展的内存缓存功能,并支持数据持久化和分布式缓存集群。 Aerospike: Aerospike 是一个高性能的 NoSQL 数据库和缓存平台,专注于提供低延迟和高吞吐量的数据访问。它支持内存和闪存存储,并具有分布式缓存的功能。 Oracle Coherence: Oracle Coherence 是一个企业级的分布式缓存和数据网格解决方案。它提供了高可用性、可扩展性和事务支持,并支持多种缓存策略和数据复制模式。

2023-09-25 1 min

Java设计模式:Bytecode

本文主要介绍 Bytecode 模式,在 Java Design Patterns 网站上有对该模式进行介绍。这里主要是做个笔记,并添加一些扩展,以加深对该设计模式的理解。 介绍 字节码设计模式是一种软件设计模式,它允许以数据驱动的方式定义和执行行为。在字节码设计模式中,行为被表示为一系列虚拟机指令,这些指令被编码为字节码,并在运行时执行。 字节码设计模式的目的是将行为与代码分离,使得行为可以在不修改源代码的情况下进行动态调整和扩展。通过将行为以数据的形式表示,并使用字节码指令进行执行,可以实现更灵活和可配置的行为逻辑。 下面是字节码设计模式的一些关键要点: 指令集:字节码设计模式通过定义一组指令集来表示不同的行为。每个指令都有自己的语义和操作方式,用于执行特定的行为逻辑。 虚拟机:字节码设计模式需要一个虚拟机来执行指令集。虚拟机负责解释和执行字节码指令,并根据指令的要求进行相应的操作。 数据驱动的行为:字节码设计模式的核心思想是将行为表示为数据而不是代码。行为逻辑由字节码指令和相关数据组成,这些数据可以在运行时进行修改和配置,从而改变程序的行为。 动态性和灵活性:由于行为以数据形式存在,并且可以在运行时进行调整,字节码设计模式具有很高的动态性和灵活性。这使得开发人员可以根据需要动态地配置和修改行为,而无需修改源代码。 可重用性和扩展性:字节码设计模式提供了一种可重用和可扩展的方式来定义行为。通过定义不同的指令和指令集,可以构建具有不同行为的模块,并在不同的上下文中重复使用这些模块。 字节码设计模式在游戏开发、模拟器、脚本引擎等领域中具有广泛的应用。它使得开发人员能够以更灵活和动态的方式定义和管理程序的行为,从而提供了更高的可配置性和可扩展性。 举例 一个常见的例子是在游戏开发中使用字节码设计模式来定义角色的行为。假设我们有一个角色类(Character),它具有各种行为,例如攻击、防御、移动等。而这些行为的具体逻辑可能会根据游戏的需求而变化。 使用字节码设计模式,我们可以将角色的行为表示为一系列字节码指令,并通过虚拟机来执行这些指令,以实现角色的行为逻辑。 下面是一个简化的示例: 定义指令集: 我们定义一组指令来表示角色的行为,例如: ATTACK:进行攻击操作 DEFEND:进行防御操作 MOVE:进行移动操作 创建虚拟机: 我们创建一个虚拟机(VirtualMachine)类,它接收字节码作为输入,并执行相应的指令。虚拟机可以解释字节码指令,并根据指令的要求执行相应的行为逻辑。 定义角色行为: 我们创建一个角色(Character)类,它包含一个字节码数组,用于表示角色的行为。例如: byte[] bytecode = {ATTACK, MOVE, ATTACK, DEFEND}; 执行角色行为: 我们将角色的字节码传递给虚拟机,并执行角色的行为逻辑: VirtualMachine vm = new VirtualMachine(); vm.execute(bytecode); 虚拟机会解释字节码指令,并根据指令执行相应的行为。例如,当遇到 ATTACK 指令时,虚拟机会执行攻击操作;当遇到 MOVE 指令时,虚拟机会执行移动操作,依此类推。 除了游戏开发之外,字节码设计模式还在其他领域中有一些应用。以下是一些常见的应用领域: 脚本引擎:字节码设计模式可用于实现脚本引擎,其中脚本语言的行为逻辑被表示为字节码指令。这种设计使得脚本的执行可以更高效和灵活,同时还可以提供动态性和扩展性。 模拟器:在模拟器开发中,字节码设计模式可以用于定义和执行模拟器的指令集。模拟器可以通过解释和执行字节码指令来模拟不同的操作和行为,从而实现对特定系统或环境的模拟。 动态编程语言:一些动态编程语言(如 Python、Ruby 等)使用字节码设计模式来实现动态性和灵活性。这些语言将代码编译为字节码,并使用虚拟机来执行字节码指令,从而提供动态类型、动态绑定和运行时修改代码等特性。 JIT 编译器:即时编译器(Just-in-Time Compiler)可以使用字节码设计模式来实现代码的即时编译和优化。在运行时,即时编译器将字节码转换为本地机器码,并对代码进行优化,以提高执行效率。 领域特定语言(DSL):字节码设计模式可以用于开发领域特定语言,其中 DSL 的行为逻辑被表示为字节码指令。这种设计使得 DSL 的执行更高效,并提供了更大的灵活性和可配置性。 需要注意的是,字节码设计模式的应用不仅限于以上领域,它可以在需要动态性、灵活性和可配置性的任何领域中发挥作用。由于字节码设计模式提供了一种将行为表示为数据的方式,使得行为可以在运行时进行调整和修改,因此在许多软件开发和系统设计的场景中都具有潜在的应用价值。 适用场景 字节码设计模式适用于以下场景: 动态行为需求:当系统需要在运行时动态地定义、配置或修改行为时,字节码设计模式可以提供一种灵活的方式。它允许将行为表示为字节码指令,以便在需要时进行调整和修改,而无需修改源代码。 可配置性和可扩展性要求:如果系统需要具有高度可配置和可扩展的行为逻辑,字节码设计模式可以提供一种解决方案。通过将行为表示为字节码指令和相关数据,开发人员可以轻松地定义和管理不同的行为模块,并在不同的上下文中重复使用这些模块。 脚本引擎和动态语言实现:字节码设计模式可以用于实现脚本引擎或支持动态语言的运行时环境。它可以将脚本行为表示为字节码指令,从而提供动态性、灵活性和执行效率。 模拟和仿真系统:在模拟和仿真系统中,字节码设计模式可以用于定义和执行模拟器的行为。通过使用字节码指令来表示各种操作和行为,可以实现对特定系统或环境的准确模拟。 编译器和优化器开发:字节码设计模式可用于开发编译器、优化器和即时编译器。它提供了一种将源代码转换为字节码指令,并在运行时进行优化和执行的方式,以提高程序的性能和效率。 总的来说,字节码设计模式在需要动态性、灵活性、可配置性和可扩展性的场景中都有应用价值。它可以用于开发各种类型的系统,包括游戏引擎、脚本引擎、模拟器、编译器、优化器等。

2023-09-22 1 min

[译]SPRING BOOT JWT - 如何使用 SPRING SECURITY 和 JSON WEB 令牌保护您的 REST API

如果您快速搜索如何使用 JSON Web Tokens 在 Spring Boot 中保护 REST API,您会发现很多相同的结果。这些结果包含一种方法,该方法涉及编写自定义过滤器链并引入第三方库来编码和解码 JWT。 在看完这些令人费解且令人困惑的教程后,我说必须有一种更简单的方法来做到这一点。我做了任何直接接触 Spring Security 团队的人都会做的事情,我向他们寻求帮助。他们告诉我,Spring Security 确实使用 oAuth2 资源服务器内置了对 JWT 的支持。 在本教程中,您将学习如何使用 JSON Web Tokens (JWT) 和 Spring Security 来保护您的 API。我并不是说这种方法无论如何都很容易,但对我来说,它比其他选择更有意义。 Github 存储库 应用架构 在我们开始编写一些代码之前,我想确保我们对于我们正在构建的内容都达成共识。在下面的示例中,您有一个客户端应用程序,它可以是一个简单的命令行应用程序、一个用 Angular 或 Vue 等编写的完整前端应用程序,或者系统中的其他一些服务。 该客户端应用程序将调用使用 Spring Boot 编写的服务器应用程序,该应用程序通过 REST API 公开数据。在下面的示例中,它是一个整体,但如果您有分布式架构,则同样适用。当前有 3 个 REST 控制器公开资源产品、订单和客户。 您要做的是保护所有资源,以便当客户端调用 REST API 时,客户端将收到 401(未经授权),这意味着客户端请求尚未完成,因为它缺少所请求资源的有效身份验证凭据。 JSON 网络令牌 (JWT) JSON Web 令牌是一种开放方法,用于在两方之间安全地表示声明。 JWT 是一组声明(JSON 属性-值对),它们共同构成一个 JSON 对象。它由三部分组成: Header: 由两个属性组成:{ “alg”: “HS256”, “typ”: “JWT” }。 alg 是用于加密 JWT 的算法。 Payload: 这是存储要发送的数据的地方;该数据存储为 JSON 属性-值对。 Signature: 这是通过加密创建的,使用标头中指定的算法:(i)base64Url 编码的标头,(ii)base64Url 编码的有效负载,以及(iii)秘密(或私钥): HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret|privateKey) 最终的 JWT 由三部分组成。每个都是 base64Url 编码的,并且与下一个之间用点分隔。有关更多详细信息,请参阅 openid.net 和 jwt.io 网站。...

[译]Spring Security 与 JWT for REST API

免责声明:Spring Security 5+ 已发布 OAuth JWT 支持。建议使用最新版本的 OAuth 来支持 JWT,而不是使用自定义安全性或过滤器。 Spring 被认为是 Java 生态系统中值得信赖的框架,并且被广泛使用。将 Spring 称为框架不再有效,因为它更多的是涵盖各种框架的总括术语。其中一个框架是 Spring Security,它是一个功能强大且可定制的身份验证和授权框架。它被认为是保护基于 Spring 的应用程序的事实标准,因此,如果您希望实现 Spring JWT 令牌解决方案,那么将其基于 Spring Security 是有意义的。 尽管它很受欢迎,但我必须承认,当涉及到单页应用程序时,Spring 的配置并不简单和直接。我怀疑原因是它更多地是作为一个面向应用程序的 MVC 框架开始的,其中网页渲染发生在服务器端,并且通信是基于会话的。 如果后端基于 Java 和 Spring,那么使用 Spring Security 和 JWT 进行身份验证/授权并将其配置为无状态通信是有意义的。虽然有很多文章解释了这是如何完成的,但对我来说,第一次设置它仍然令人沮丧,我必须阅读并总结来自多个来源的信息。这就是我决定编写这个 Spring Security 教程的原因,我将在其中尝试总结并涵盖您在配置过程中可能遇到的所有必需的微妙细节和缺陷。 术语定义 在深入探讨技术细节之前,我想明确定义 Spring Security 上下文中使用的术语,以确保我们都使用相同的语言。 这些是我们需要解决的术语: Authentication 验证是指根据提供的凭据验证用户身份的过程。一个常见的示例是在登录网站时输入用户名和密码。您可以将其视为对“您是谁?”这个问题的答案。 Authorization 授权是指假设用户已成功通过身份验证,则确定用户是否具有执行特定操作或读取特定数据的适当权限的过程。您可以将其视为“用户可以执行/阅读此操作吗?”问题的答案。 Principle 原则是指当前经过身份验证的用户。 Granted authority 授予权限是指经过认证的用户的权限。 Role 角色是指经过身份验证的用户的一组权限。 创建基本的 Spring 应用程序 在开始配置 Spring Security 框架之前,让我们创建一个基本的 Spring Web 应用程序。为此,我们可以使用 Spring Initializr 并生成一个模板项目。对于一个简单的 Web 应用程序,只需要 Spring Web 框架依赖就足够了: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> 创建项目后,我们可以向其中添加一个简单的 REST 控制器,如下所示: @RestController @RequestMapping("hello") public class HelloRestController { @GetMapping("user") public String helloUser() { return "Hello User"; } @GetMapping("admin") public String helloAdmin() { return "Hello Admin"; } } 之后,如果我们构建并运行该项目,我们可以在 Web 浏览器中访问以下 URL:...