1. 简介

在这篇文章中,我们将深入了解如何使用 Spring Cloud Function 开发函数式服务。

✅ 我们将从零开始搭建一个简单的项目,实现两个函数功能:

  • 字符串反转(使用普通方法)
  • 欢迎语生成器(使用类实现)

然后分别在本地运行测试,并最终部署到 AWS 上。


2. Spring Cloud Function 环境准备

2.1. Maven 依赖配置

首先,我们需要添加 spring-cloud-starter-function-web 这个依赖。它将作为本地运行的适配器,帮助我们快速启动并测试函数。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-function-web</artifactId>
    <version>1.0.1.RELEASE</version>
</dependency>

⚠️ 注意:当我们部署到云平台时,这个依赖会被替换为特定平台的适配器。


2.2. 编写第一个 Spring Cloud Function

通过 Spring Cloud Function,我们可以把类型为 FunctionConsumerSupplier@Bean 方法暴露为函数接口。

例如,下面是一个字符串反转函数:

@SpringBootApplication
public class CloudFunctionApplication {

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

    @Bean
    public Function<String, String> reverseString() {
        return value -> new StringBuilder(value).reverse().toString();
    }
}

✅ 这样定义之后,这个函数就可以被函数式平台调用了。


2.3. 本地测试字符串反转函数

spring-cloud-starter-function-web 会自动将函数暴露为 HTTP 接口。启动应用后,可以使用 curl 来测试:

curl localhost:8080/reverseString -H "Content-Type: text/plain" -d "Baeldung User"

📌 接口路径就是 @Bean 的方法名。

返回结果如下:

resU gnudleaB

2.4. 使用类方式定义函数并扫描包

除了使用 @Bean,我们也可以创建一个类实现 Function<T, R> 接口:

public class Greeter implements Function<String, String> {

    @Override
    public String apply(String s) {
        return "Hello " + s + ", and welcome to Spring Cloud Function!!!";
    }
}

然后,在 application.properties 中配置要扫描的包路径:

spring.cloud.function.scan.packages=com.baeldung.spring.cloudfunction.functions

2.5. 本地测试 Greeter 函数

启动应用后,使用 curl 测试:

curl localhost:8080/greeter -H "Content-Type: text/plain" -d "World"

📌 接口名就是类名。

返回结果:

Hello World, and welcome to Spring Cloud function!!!

3. 部署 Spring Cloud Function 到 AWS

3.1. Maven 依赖调整

之前我们使用的是 spring-cloud-starter-function-web,现在要替换成 AWS 的适配器依赖:

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

此外,添加 AWS Lambda 相关依赖:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-events</artifactId>
    <version>2.0.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-core</artifactId>
    <version>1.1.0</version>
    <scope>provided</scope>
</dependency>

为了生成可上传到 AWS 的 JAR 包,我们还需要使用 maven-shade-pluginspring-boot-thin-layout 插件来打包:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
        <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>1.0.10.RELEASE</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
                <shadedArtifactAttached>true</shadedArtifactAttached>
                <shadedClassifierName>aws</shadedClassifierName>
            </configuration>
        </plugin>
    </plugins>
</build>

3.2. AWS Handler 实现

为了在 AWS Lambda 中暴露我们的函数,我们需要继承 SpringBootRequestHandler

public class MyStringHandlers extends SpringBootRequestHandler<String, String> {

}

虽然这个类是空的,但它定义了 Lambda 的入口和输入输出类型。

📌 后续我们会在 AWS 控制台中指定这个类的全限定名作为 Handler。


3.3. AWS 如何知道调用哪个函数?

即使我们在应用中定义了多个函数,AWS Lambda 一次只能调用一个。

我们通过环境变量 FUNCTION_NAME 来告诉 AWS 要调用哪个函数。


4. 上传函数到 AWS 并测试

4.1. 在 AWS 控制台创建并配置 Lambda 函数

在 AWS Lambda 控制台页面中,选择 Java 8 运行时,然后上传我们构建好的 JAR 包。

Handler 字段中填写:

com.baeldung.spring.cloudfunction.MyStringHandlers

接着在 Environment variables 中添加:

FUNCTION_NAME=reverseString

配置如下图所示:

cloud1

cloud2

然后创建一个测试事件,输入字符串:

cloud3


4.2. 测试函数

保存测试事件后点击 Test,得到如下输出:

cloud4

✅ 和本地测试结果一致。


4.3. 测试另一个函数

我们还有一个 greeter 函数。只需将环境变量 FUNCTION_NAME 改为 greeter

cloud5

再次点击 SaveTest,结果如下:

cloud6

✅ 成功!


5. 总结

虽然 Spring Cloud Function 还在早期阶段,但它已经是一个非常强大的工具,可以让我们将业务逻辑与运行时环境解耦。

✅ 同一份代码可以:

  • 作为 Web 接口运行
  • 部署到云平台(如 AWS、Azure、GCP)
  • 用于流处理场景

它隐藏了传输细节和基础设施,让开发者可以专注于业务逻辑,同时继续使用熟悉的工具和流程。

📌 本文示例代码可在这里查看:GitHub 源码


原始标题:Serverless Functions with Spring Cloud Function | Baeldung