请使用 spring-cloud-function 5.0.1 获取最新稳定版本!spring-doc.cadn.net.cn

AWS Lambda

AWS 适配器可将 Spring Cloud Function 应用转换为可在 AWS Lambda 中运行的形式。spring-doc.cadn.net.cn

一般来说,在 AWS Lambda 上运行 Spring 应用程序有两种方式:spring-doc.cadn.net.cn

  1. 通过 Spring Cloud Function 的 AWS Lambda 适配器实现上述功能化方法。这非常适合单职责 API 以及事件和消息驱动型系统,例如处理来自 Amazon SQS 或 Amazon MQ 队列的消息、Apache Kafka 流中的数据,或响应 Amazon S3 中的文件上传。spring-doc.cadn.net.cn

  2. 通过 Serverless Java 容器项目 在 AWS Lambda 上运行 Spring Boot Web 应用程序。该方案非常适合将现有 Spring 应用迁移至 AWS Lambda,或在构建具有多个 API 端点的复杂 API 时,希望保持熟悉的 RestController 开发方式。此方法的详细说明请参见 Spring Boot Web 的 Serverless Java 容器spring-doc.cadn.net.cn

以下指南假设您已具备基本的 AWS 和 AWS Lambda 知识,并重点介绍 Spring 所提供的额外价值。有关如何开始使用 AWS Lambda 的详细信息超出了本文档的范围。如果您想了解更多信息,可以访问 AWS Lambda 基础概念 或完整的 Java on AWS 概览spring-doc.cadn.net.cn

快速开始

Spring Cloud Function 框架的目标之一是提供必要的基础设施元素,以使一个 简单的函数式应用 能够与特定环境(如 AWS Lambda)兼容。spring-doc.cadn.net.cn

在 Spring 的上下文中,一个简单的功能型应用程序包含类型为 SupplierFunctionConsumer 的 Bean。spring-doc.cadn.net.cn

让我们来看一个示例:spring-doc.cadn.net.cn

@SpringBootApplication
public class FunctionConfiguration {

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

	@Bean
	public Function<String, String> uppercase() {
		return value -> value.toUpperCase();
	}
}

您可以看到一个完整的 Spring Boot 应用程序,其中定义了一个功能 Bean。表面上这只是一个普通的 Spring Boot 应用程序。然而,当向项目中添加 Spring Cloud Function AWS Adapter 后,它将变为一个完全有效的 AWS Lambda 应用程序:spring-doc.cadn.net.cn

<dependencies>
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-function-adapter-aws</artifactId>
 </dependency>
</dependencies>

无需其他代码或配置。我们已提供一个可直接构建并部署的示例项目。您可在官方 Spring Cloud Function 示例仓库中访问它 (此处为链接)spring-doc.cadn.net.cn

您只需执行 mvn clean package 即可生成 JAR 文件。所有必要的 Maven 插件均已配置完毕,以生成适用于 AWS 部署的适当 JAR 文件。(您可以在 JAR 布局说明 中了解有关 JAR 文件结构的更多详情)。spring-doc.cadn.net.cn

AWS Lambda 函数处理器

与传统通过监听特定HTTP端口(如80、443)暴露功能的Web应用不同,AWS Lambda函数是在预定义的入口点(称为Lambda 函数处理器)处被调用的。spring-doc.cadn.net.cn

我们建议使用内置的org.springframework.cloud.function.adapter.aws.FunctionInvoker处理器,以简化与AWS Lambda的集成。它开箱即用地提供了高级功能,例如多函数路由、与AWS细节解耦以及POJO序列化。请参阅AWS请求处理器AWS函数路由部分以了解更多信息。spring-doc.cadn.net.cn

部署

构建应用程序后,您可以手动通过 AWS 控制台、AWS 命令行界面(CLI)或基础设施即代码(IaC)工具(如 AWS Serverless Application Model(AWS SAM)AWS Cloud Development Kit(AWS CDK)AWS CloudFormationTerraform)部署 JAR 文件。spring-doc.cadn.net.cn

在 AWS 控制台中创建一个 Hello World Lambda 函数spring-doc.cadn.net.cn

  1. 打开 Lambda 控制台的功能页面spring-doc.cadn.net.cn

  2. 选择 创建函数spring-doc.cadn.net.cn

  3. 选择 从头开始编写作者spring-doc.cadn.net.cn

  4. 对于函数名,请输入 MySpringLambdaFunctionspring-doc.cadn.net.cn

  5. 对于运行时,选择 Java 21spring-doc.cadn.net.cn

  6. 选择 创建函数spring-doc.cadn.net.cn

上传您的代码并测试功能:spring-doc.cadn.net.cn

  1. 上传之前创建的 JAR 文件,例如 target/function-sample-aws-0.0.1-SNAPSHOT-aws.jarspring-doc.cadn.net.cn

  2. 提供入口处理方法 org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequestspring-doc.cadn.net.cn

  3. 转到“测试”选项卡并点击“测试”按钮。该函数应以大写形式返回提供的 JSON 负载。spring-doc.cadn.net.cn

aws spring lambda edit
aws spring lambda test

要使用基础设施即代码(IaC)工具自动化您的部署,请参阅 AWS 官方文档spring-doc.cadn.net.cn

AWS 请求处理器

如“快速入门”部分所述,AWS Lambda 函数会在一个预定义的入口点(称为 Lambda 函数处理器)处被调用。在最简单的情况下,这可以是一个 Java 方法引用。在上面的例子中,这将是 com.my.package.FunctionConfiguration::uppercase。此配置用于告知 AWS Lambda 在提供的 JAR 文件中应调用哪个 Java 方法。spring-doc.cadn.net.cn

当 Lambda 函数被调用时,它会向此处理方法传递一个额外的请求负载和上下文对象。请求负载根据触发函数的 AWS 服务(如 Amazon API Gateway、Amazon S3、Amazon SQS、Apache Kafka 等)而有所不同。上下文对象则提供了关于 Lambda 函数、调用及环境的额外信息,例如唯一的请求 ID(参见官方文档中的 Java 上下文)。spring-doc.cadn.net.cn

AWS 提供了预定义的处理程序接口(称为 RequestHandlerRequestStreamHandler),通过 aws-lambda-java-events 和 aws-lambda-java-core 库来处理负载(payload)和上下文(context)对象。spring-doc.cadn.net.cn

Spring Cloud Function 已经实现了这些接口,并提供了一个 org.springframework.cloud.function.adapter.aws.FunctionInvoker,可完全将您的函数代码与 AWS Lambda 的具体细节相分离。这使得您只需根据运行函数的平台切换入口点即可。spring-doc.cadn.net.cn

然而,对于某些用例,您可能希望深度集成到 AWS 环境中。例如,当您的函数由 Amazon S3 文件上传触发时,您可能需要访问特定的 Amazon S3 属性。或者,如果您希望在处理来自 Amazon SQS 队列的消息项时返回部分批响应。在这种情况下,您仍然可以利用通用的 org.springframework.cloud.function.adapter.aws.FunctionInvoker,但将在您的函数代码中使用专用的 AWS 对象:spring-doc.cadn.net.cn

@Bean
public Function<S3Event, String> processS3Event() {}

@Bean
public Function<SQSEvent, SQSBatchResponse> processSQSEvent() {}

类型转换

利用内置的 FunctionInvoker 的另一个好处是,Spring Cloud Function 将尝试透明地处理原始输入流与您的函数所声明的类型之间的类型转换。spring-doc.cadn.net.cn

例如,如果您的函数签名是 Function<Foo, Bar>,它将尝试将传入的流事件转换为 Foo 的实例。这在由 API 触发的 Lambda 函数中特别有用,因为请求体代表一个业务对象,且与 AWS 具体细节无关。spring-doc.cadn.net.cn

如果事件类型未知或无法确定(例如,Function<?, ?>),Spring Cloud Function 将尝试将传入的流事件转换为通用的 Mapspring-doc.cadn.net.cn

原始输入

有时,您可能需要访问原始输入。此时,您只需将函数签名声明为接受 InputStream,例如 Function<InputStream, ?>spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

如果已指定,Spring Cloud Function 将不会尝试任何转换,并会直接将原始输入传递给函数。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

AWS 函数路由

Spring Cloud Function 的核心特性之一是 路由。此功能允许您将一个特殊的 Java 方法(作为 Lambda 函数处理器)用作委托,以调用其他内部方法。您已经在 入门指南 章节中看到过这一功能的实际应用:通用的 FunctionInvoker 自动将请求路由至您的 uppercase 函数。spring-doc.cadn.net.cn

默认情况下,如果您的应用包含多个类型为 @BeanFunction 等组件,它们将从 Spring Cloud FunctionCatalog 中提取,框架将尝试按照搜索顺序查找默认值:首先搜索 Function,然后是 Consumer,最后是 Supplier。这些默认路由功能是必需的,因为 FunctionInvoker 无法确定应绑定哪个函数,因此它在内部默认采用 RoutingFunction。建议通过多种机制 提供额外的路由指令(详见 示例 以获取更多详细信息)。spring-doc.cadn.net.cn

正确的路由机制取决于您将 Spring Cloud Function 项目部署为单个 Lambda 函数还是多个 Lambda 函数的偏好。spring-doc.cadn.net.cn

单一功能 vs. 多个功能

如果您在同一个 Spring Cloud Function 项目中实现了多个 Java 方法,例如 uppercaselowercase,您可以选择部署两个独立的 Lambda 函数并使用静态路由信息,或者提供一种动态路由机制,在运行时决定调用哪个方法。让我们分别探讨这两种方法。spring-doc.cadn.net.cn

  1. 部署两个独立的 AWS Lambda 函数在您对每个函数有不同的扩展性、配置或权限要求时是合理的。例如,如果您在同一个 Spring Cloud Function 项目中创建了两个 Java 方法 readObjectFromAmazonS3writeToAmazonDynamoDB,可能希望创建两个独立的 Lambda 函数。这是因为它们需要不同的权限才能分别与 S3 或 DynamoDB 进行通信,或者其负载模式和内存配置存在显著差异。一般来说,对于基于消息的应用程序(例如从流或队列中读取数据),这种做法也推荐使用,因为每个 Lambda 事件源映射 都有专属的配置。spring-doc.cadn.net.cn

  2. 当多个 Java 方法共享相同的权限集或提供统一的业务功能时,使用单个 Lambda 函数是一种可行的方法。例如,一个基于 CRUD 的 Spring Cloud Function 项目中包含 createPetupdatePetreadPetdeletePet 等方法,它们均访问同一张 DynamoDB 表,并具有相似的使用模式。采用单个 Lambda 函数可提升部署的简便性、内聚性以及共享类(PetEntity)的代码复用性。此外,它还能减少连续调用之间的冷启动现象,因为 readPet 后接 writePet 时,极大概率会命中已运行的 Lambda 执行环境。然而,若您构建更复杂的 API,或希望利用 @RestController 的方法,则还可考虑评估 适用于 Spring Boot Web 的 Serverless Java 容器 这一选项。spring-doc.cadn.net.cn

如果您倾向于第一种方法,也可以创建两个独立的 Spring Cloud Function 项目并分别部署。如果不同的团队负责维护和部署这些函数,这种做法会带来便利。然而,在这种情况下,您需要处理它们之间的横向关注点共享问题,例如辅助方法或实体类。总体而言,我们建议将与传统 Web 应用相同的软件模块化原则应用于您的函数项目中。有关如何选择合适方法的更多信息,您可以参考 比较无服务器微服务的设计方法spring-doc.cadn.net.cn

在做出决定后,您可以利用以下路由机制。spring-doc.cadn.net.cn

多个 Lambda 函数的路由

如果您已决定将单个 Spring Cloud Function 项目(JAR)部署到多个 Lambda 函数,您需要提供一个提示,以指示调用哪个特定方法,例如 uppercaselowercase。您可以使用 AWS Lambda 环境变量 来提供路由指令。spring-doc.cadn.net.cn

注意,AWS 不允许在环境变量名称中使用点号 . 和/或连字符 -。您可以利用 Spring Boot 的支持,只需将点号替换为下划线,连字符替换为驼峰命名法即可。例如,spring.cloud.function.definition 变为 spring_cloud_function_definitionspring.cloud.function.routing-expression 变为 spring_cloud_function_routingExpressionspring-doc.cadn.net.cn

因此,一个单个 Spring Cloud 项目配置,其中包含两种方法并分别部署到不同的 AWS Lambda 函数中,可能如下所示:spring-doc.cadn.net.cn

@SpringBootApplication
public class FunctionConfiguration {

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

	@Bean
	public Function<String, String> uppercase() {
		return value -> value.toUpperCase();
	}

    @Bean
	public Function<String, String> lowercase() {
		return value -> value.toLowerCase();
	}
}
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyUpperCaseLambda:
    Type: AWS::Serverless::Function
    Properties:
      Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker
      Runtime: java21
      MemorySize: 512
      CodeUri: target/function-sample-aws-0.0.1-SNAPSHOT-aws.jar
      Environment:
        Variables:
          spring_cloud_function_definition: uppercase

  MyLowerCaseLambda:
    Type: AWS::Serverless::Function
    Properties:
      Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker
      Runtime: java21
      MemorySize: 512
      CodeUri: target/function-sample-aws-0.0.1-SNAPSHOT-aws.jar
      Environment:
        Variables:
          spring_cloud_function_definition: lowercase

您可能会问——为什么不直接使用 Lambda 函数处理器,并将入口方法指向 uppercaselowercase?在 Spring Cloud Function 项目中,建议使用内置的 FunctionInvoker,如 AWS 请求处理器 中所述。因此,我们通过环境变量提供路由定义。spring-doc.cadn.net.cn

单个 Lambda 函数内的路由

如果您已决定将您的 Spring Cloud Function 项目(包含多个方法(uppercaselowercase))部署到单个 Lambda 函数中,您需要一种更动态的路由方案。由于 application.properties 和环境变量是在构建或部署时定义的,因此在单函数场景下无法使用它们。此时,您可以按照 Spring Cloud Function 路由部分 所述,利用 MessagingRoutingCallbackMessage Headersspring-doc.cadn.net.cn

更多详情请参阅提供的示例spring-doc.cadn.net.cn

性能考虑

无服务器函数的核心特性之一是能够扩展至零并处理突发的流量高峰。为处理请求,AWS Lambda 会启动新的执行环境 新的执行环境。这些环境需要进行初始化,您的代码需被下载,同时 JVM 和您的应用程序也需启动。这一过程也被称为“冷启动”。为减少此冷启动时间,您可以依靠以下机制来优化性能。spring-doc.cadn.net.cn

  1. 利用 AWS Lambda SnapStart 从预初始化快照中启动您的 Lambda 函数。spring-doc.cadn.net.cn

  2. 通过 AWS Lambda 功率调优来调整内存配置,以找到性能与成本之间的最佳权衡。spring-doc.cadn.net.cn

  3. 遵循 AWS SDK 最佳实践,例如将 SDK 客户端定义在处理程序代码之外,或利用更高级的预热技术。spring-doc.cadn.net.cn

  4. 实现额外的 Spring 机制以减少 Spring 启动和初始化时间,例如 函数式 Bean 注册spring-doc.cadn.net.cn

请参考官方指南获取更多信息。spring-doc.cadn.net.cn

GraalVM 原生映像

Spring Cloud Function 为在 AWS Lambda 上运行的函数提供了 GraalVM 原生镜像支持。由于 GraalVM 原生镜像无法在传统的 Java 虚拟机(JVM)上运行,您必须将原生 Spring Cloud Function 部署到 AWS Lambda 自定义运行时。最显著的区别在于,您不再提供 JAR 文件,而是将原生镜像和一个包含启动说明的引导文件打包成一个 ZIP 包:spring-doc.cadn.net.cn

lambda-custom-runtime.zip
  |-- bootstrap
  |-- function-sample-aws-native

Bootstrap file:spring-doc.cadn.net.cn

#!/bin/sh

cd ${LAMBDA_TASK_ROOT:-.}

./function-sample-aws-native

自定义运行时

Lambda 专注于提供稳定长期支持(LTS)的 Java 运行时版本。官方 Lambda 运行时基于操作系统、编程语言和软件库的组合构建,这些组件会定期接受维护和安全更新。例如,Lambda 的 Java 运行时支持 LTS 版本,如 Java 17 Corretto 和 Java 21 Corretto。您可以在 此处 查看完整列表。对于非 LTS 版本(如 Java 22、Java 23 或 Java 24),官方未提供运行时。spring-doc.cadn.net.cn

要使用其他语言版本、JVM 或 GraalVM 原生镜像,Lambda 允许您 创建自定义运行时。自定义运行时使您能够提供并配置自己的运行时环境以运行您的应用代码。Spring Cloud Function 提供了所有必要的组件,使此过程变得简单。spring-doc.cadn.net.cn

从代码角度而言,该应用在外观上应与其他任何 Spring Cloud Function 应用无异。您只需在 ZIP/JAR 文件的根目录中提供一个 bootstrap 脚本,以运行 Spring Boot 应用即可。在 AWS 中创建函数时,请选择“自定义运行时”。以下是一个示例 'bootstrap' 文件:spring-doc.cadn.net.cn

#!/bin/sh

cd ${LAMBDA_TASK_ROOT:-.}

java -Dspring.main.web-application-type=none -Dspring.jmx.enabled=false \
  -noverify -XX:TieredStopAtLevel=1 -Xss256K -XX:MaxMetaspaceSize=128M \
  -Djava.security.egd=file:/dev/./urandom \
  -cp .:`echo lib/*.jar | tr ' ' :` com.example.LambdaApplication

The com.example.LambdaApplication represents your application which contains function beans.spring-doc.cadn.net.cn

在 AWS 中将处理器名称设置为您的函数名称。您也可以在此处使用函数组合(例如,uppercase|reverse)。
一旦您将 ZIP/JAR 文件上传至 AWS,您的函数将在自定义运行时中运行。
我们提供了一个示例项目,您还可以在此了解如何配置 POM 文件以正确生成 ZIP 文件。spring-doc.cadn.net.cn

功能型 Bean 定义风格同样适用于自定义运行时,且比 @Bean 风格更快。即使在 Java Lambda 的功能型 Bean 实现中,自定义运行时的启动速度也可能更快——这主要取决于运行时需要加载的类的数量。Spring 在此处并不做太多操作,因此您可以通过在函数中仅使用基本数据类型(例如),避免在自定义 @PostConstruct 初始化器中执行任何操作,从而减少冷启动时间。spring-doc.cadn.net.cn

AWS 函数路由与自定义运行时

当使用 自定义运行时 时,函数路由的工作方式相同。您只需将 functionRouter 指定为 AWS 处理程序,就像您将函数名称用作处理程序一样。spring-doc.cadn.net.cn

部署 Lambda 函数为容器镜像

与基于 JAR 或 ZIP 的部署不同,您还可以通过镜像注册表将 Lambda 函数作为容器镜像进行部署。有关更多详细信息,请参阅 AWS Lambda 官方文档spring-doc.cadn.net.cn

在以类似于 此处 所描述的方式部署容器镜像时,重要的是要记得将环境变量 DEFAULT_HANDLER 设置为函数的名称。spring-doc.cadn.net.cn

例如,对于下面所示的功能 Bean,DEFAULT_HANDLER 的值将是 readMessageFromSQSspring-doc.cadn.net.cn

@Bean
public Consumer<Message<SQSMessageEvent>> readMessageFromSQS() {
	return incomingMessage -> {..}
}

此外,还应记住确保将 spring_cloud_function_web_export_enabled 也设置为 false。其默认值为 truespring-doc.cadn.net.cn

JAR 布局说明

在 Lambda 运行时,您无需 Spring Cloud Function Web 或 Stream 适配器,因此在将 JAR 文件发送至 AWS 之前,可能需要排除这些依赖项。Lambda 应用程序必须进行打包(shaded),而 Spring Boot 独立应用程序则不需要,因此您可以使用两个独立的 JAR 文件运行同一应用程序(如示例所示)。该示例应用程序会创建两个 JAR 文件,其中一个包含aws用于在 Lambda 中部署的分类器,以及一个可执行(精简)JAR包,其中包含spring-cloud-function-web在运行时,Spring Cloud Function 将尝试从 JAR 文件的清单(manifest)中为您定位一个“主类”。Start-Class属性(如果您使用Starters父项目,Spring Boot 工具将为您自动添加此属性)。如果没有Start-Class在您的清单文件中,您可以使用环境变量或系统属性MAIN_CLASS当你将该函数部署到 AWS 时。spring-doc.cadn.net.cn

如果您未使用函数式 Bean 定义,而是依赖 Spring Boot 的自动配置,并且不依赖 spring-boot-starter-parent,则必须将额外的转换器作为 maven-shade-plugin 执行的一部分进行配置。spring-doc.cadn.net.cn

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-shade-plugin</artifactId>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<version>3.4.2</version>
		</dependency>
	</dependencies>
	<executions>
		<execution>
			<goals>
			     <goal>shade</goal>
			</goals>
			<configuration>
				<createDependencyReducedPom>false</createDependencyReducedPom>
				<shadedArtifactAttached>true</shadedArtifactAttached>
				<shadedClassifierName>aws</shadedClassifierName>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.handlers</resource>
					</transformer>
					<transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
						<resource>META-INF/spring.factories</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.schemas</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.components</resource>
					</transformer>
				</transformers>
			</configuration>
		</execution>
	</executions>
</plugin>

构建文件设置

为了在 AWS Lambda 上运行 Spring Cloud Function 应用程序,您可以利用 Maven 或 Gradle 插件。spring-doc.cadn.net.cn

Maven

为了使用 Maven 的适配器插件,请将插件依赖项添加到您的 pom.xml 文件中:spring-doc.cadn.net.cn

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-function-adapter-aws</artifactId>
	</dependency>
</dependencies>

正如《JAR 布局说明》(Notes on JAR Layout)中指出的那样,您需要一个“阴影”(shaded)JAR包才能将其上传至 AWS Lambda。您可以使用 Maven Shade Plugin 来完成此操作。上述示例中的 设置 可供参考。spring-doc.cadn.net.cn

您可以使用 Spring Boot Maven 插件来生成 瘦 jarspring-doc.cadn.net.cn

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot.experimental</groupId>
			<artifactId>spring-boot-thin-layout</artifactId>
			<version>${wrapper.version}</version>
		</dependency>
	</dependencies>
</plugin>

您可以在此处找到完整的示例 pom.xml 文件,该文件用于使用 Maven 将 Spring Cloud Function 应用部署到 AWS Lambda:此处spring-doc.cadn.net.cn

Gradle

为了在 Gradle 中使用适配器插件,请将依赖项添加到您的 build.gradle 文件中:spring-doc.cadn.net.cn

dependencies {
	compile("org.springframework.cloud:spring-cloud-function-adapter-aws:${version}")
}

正如在JAR 布局说明中所指出的,您需要一个“阴影”(shaded)JAR 文件才能将其上传到 AWS Lambda。您可以使用Gradle Shadow 插件来实现此目的:spring-doc.cadn.net.cn

您可以使用 Spring Boot Gradle 插件和 Spring Boot Thin Gradle 插件来生成 瘦 JAR 包spring-doc.cadn.net.cn

以下是一个完整的 Gradle 文件spring-doc.cadn.net.cn

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.4.2'
	id 'io.spring.dependency-management' version '1.1.3'
	id 'com.github.johnrengelman.shadow' version '8.1.1'
	id 'maven-publish'
	id 'org.springframework.boot.experimental.thin-launcher' version "1.0.31.RELEASE"
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
	mavenLocal()
	maven { url 'https://repo.spring.io/milestone' }
}

ext {
	set('springCloudVersion', "2024.0.0")
}

assemble.dependsOn = [thinJar, shadowJar]

publishing {
	publications {
		maven(MavenPublication) {
			from components.java
			versionMapping {
				usage('java-api') {
					fromResolutionOf('runtimeClasspath')
				}
				usage('java-runtime') {
					fromResolutionResult()
				}
			}
		}
	}
}

shadowJar.mustRunAfter thinJar


import com.github.jengelman.gradle.plugins.shadow.transformers.*

shadowJar {
	archiveClassifier = 'aws'
	manifest {
    	inheritFrom(project.tasks.thinJar.manifest)
  	}
  	// Required for Spring
	mergeServiceFiles()
	append 'META-INF/spring.handlers'
	append 'META-INF/spring.schemas'
	append 'META-INF/spring.tooling'
	append 'META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports'
	append 'META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports'
	transform(PropertiesFileTransformer) {
		paths = ['META-INF/spring.factories']
		mergeStrategy = "append"
	}
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.cloud:spring-cloud-function-adapter-aws'
	implementation 'org.springframework.cloud:spring-cloud-function-context'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

tasks.named('test') {
	useJUnitPlatform()
}

您可以在此处找到完整的示例 build.gradle 文件,用于使用 Gradle 将 Spring Cloud Function 应用程序部署到 AWS Lambda:此处spring-doc.cadn.net.cn

无服务器 Java 容器用于 Spring Boot Web

您可以使用 aws-serverless-java-container 库在 AWS Lambda 中运行 Spring Boot 3 应用程序。这非常适合将现有 Spring 应用程序迁移至 AWS Lambda,或如果您构建了具有多个 API 端点的复杂 API 并希望保持熟悉的 RestController 开发方式。以下部分提供了该过程的概览。请参阅 官方示例代码 以获取更多信息。spring-doc.cadn.net.cn

  1. 将 Serverless Java Container 库导入到您现有的 Spring Boot 3 Web 应用中spring-doc.cadn.net.cn

    <dependency>
     <groupId>com.amazonaws.serverless</groupId>
     <artifactId>aws-serverless-java-container-springboot3</artifactId>
     <version>2.1.2</version>
    </dependency>
  2. 使用内置的 Lambda 函数处理程序作为入口点spring-doc.cadn.net.cn

    com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandlerspring-doc.cadn.net.cn

  3. 配置一个名为 MAIN_CLASS 的环境变量,以告知通用处理器在何处找到您的原始应用主类。通常,该类是使用 @SpringBootApplication 注解标注的类。spring-doc.cadn.net.cn

MAIN_CLAS = com.my.package.MySpringBootApplicationspring-doc.cadn.net.cn

下面您可以看到一个示例部署配置:spring-doc.cadn.net.cn

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MySpringBootLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler
      Runtime: java21
      MemorySize: 1024
      CodeUri: target/lambda-spring-boot-app-0.0.1-SNAPSHOT.jar #Must be a shaded Jar
      Environment:
        Variables:
          MAIN_CLASS: com.amazonaws.serverless.sample.springboot3.Application #Class annotated with @SpringBootApplication

请在此处找到所有包括 GraalVM native-image 的示例 此处spring-doc.cadn.net.cn