领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多Spring Cloud Function 是一个基于 Spring Boot 的框架,允许用户通过将业务逻辑实现为 Java 函数(例如 Supplier、Function、Consumer)来专注于其业务逻辑。反过来,该框架提供了必要的抽象,以便在各种环境(例如 REST、流式传输)以及无服务器环境(例如 AWS Lambda 或 Azure Functions)中执行这些函数,而无需担心底层平台特定的细节。这允许开发人员专注于编写其业务逻辑,并让框架处理其余部分。
Spring Cloud Function 使用java.util.function.Function/Supplier/Consumer
接口作为定义函数结构(包括输入和输出类型)的构建块。
这是一个简单的 Spring Cloud Function 示例,它接收一个字符串并返回大写形式的字符串
首先,我们定义函数接口
public interface UppercaseFunction extends Function<String, String> { }
接下来,我们将函数注册为 Bean
@Bean
public UppercaseFunction uppercase() {
return value -> value.toUpperCase();
}
这是一个您可以使用 Spring Cloud Function 执行的基本示例,您可以将其用于更复杂的用例,例如连接到数据库或从队列中使用消息,等等。它本身只是一段代码,实现为 Java 函数并注册为 Spring Bean。但是,使用 Spring Cloud Function,此函数可以成为 REST 请求的处理程序或由 Kafka 等消息传递系统触发的消息处理程序。相同的函数也可以在 AWS Lambda 或 Microsoft Azure 等无服务器环境中执行,而无需更改其实现。这就是这篇文章要讨论的内容,特别是 Spring Cloud Function 与 Microsoft Azure 的集成。
Azure Java Functions 是一项服务,允许您编写基于 Java 的无服务器函数,在 Azure 基础设施上运行它们,并能够与其他 Azure 服务和框架(如 Spring Boot)集成。
Azure Functions 运行时负责扩展、安全性和函数应用程序的监控,并提供与其他 Azure 服务的轻松集成。您可以在此处阅读有关 Azure Java 函数的更多信息
Spring Cloud Function 提供了一个Azure 适配器来部署和运行作为 Azure Java 函数的 Java 函数。
为了将 Spring Cloud Function 与 Azure Java 函数一起使用,您需要在类路径中包含spring-cloud-function-adapter-azure
依赖项
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
<version>4.0.4</version>
</dependency>
需要注意的是,使用 Spring Cloud Function 可以使您能够在 Azure Java 函数上使用简单的 Java 函数编程模型,但底层基础设施仍然是 Azure 函数,您仍然需要管理 Azure 函数应用程序的扩展、安全性和监控,以及与其他 Azure 服务的集成。
让我们看一下示例。为此,我们需要将业务逻辑(即字符串大写)分解到一个名为uppercase
的专用函数中
import java.util.function.Function;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class HttpTriggerDemoApplication {
@Bean
public Function<String, String> uppercase() {
return payload -> {
String output = payload.toUpperCase();
return String.format("Input: %s", output);
}
}
@Bean
public Function<String, String> reverse() {
return payload -> new StringBuilder(payload).reverse().toString();
}
public static void main(String[] args) {
SpringApplication.run(HttpTriggerDemoApplication.class, args);
}
}
此示例使用@SpringBootApplication
注释配置 Spring Boot 应用程序,并使用@Bean
注释定义函数 Bean。然后,要在 Azure Java 函数上运行此函数,您需要在 Azure 上创建一个新的函数应用程序,并将其配置为使用 Java 运行时。
import java.util.Optional;
import java.util.function.Function;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.stereotype.Component;
@Component
public class AzureJavaExampleFunctionWithSpring {
/**
* Plain Spring bean (not Spring Cloud Functions!)
*/
@Autowired
private Function<String, String> uppercase;
/**
* The FunctionCatalog leverages the Spring Cloud Function framework.
*/
@Autowired
private FunctionCatalog functionCatalog;
@FunctionName("bean")
public String plainBeans(
@HttpTrigger(name = "req", methods = { HttpMethod.GET,
HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
// Use plain Spring Beans.
return uppercase.apply(request.getBody().orElse("Hello World"));
}
@FunctionName("scf")
public String springCloudFunction(
@HttpTrigger(name = "req", methods = { HttpMethod.GET,
HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
// Use SCF composition.
Function composed = this.functionCatalog.lookup("reverse|uppercase");
return (String) composed.apply(request.getBody().orElse("Hello World"));
}
}
AzureJavaExampleFunctionWithSpring
类使用标准的 Azure 注释(例如 @FunctionName 和@HttpTrigger
)进行注释,并在内部调用HttpTriggerDemoApplication
中定义的uppercase
函数。@Component
注释使此 Azure 应用程序也成为 Spring 应用程序,从而通过 Spring 依赖项注入(例如自动连接uppercase
或functionCatalog
Bean)提供与 Spring Cloud Function 和其他 Spring 托管组件的集成点。请注意,AzureJavaExampleFunctionWithSpring
是一个功能齐全的 Spring 组件,因此您可以自动连接任何 Spring Bean(不仅仅是函数),使用属性配置和任何其他 Spring Framework 功能。
请注意,plainBeans
函数使用普通的 Spring Bean,而springCloudFunctin
利用FunctionCatalog
来组合多个 Spring Cloud 函数。
您需要将函数打包为一个 fat jar,然后将其部署到您的 Azure 函数应用。部署后,您可以通过 HTTP 请求或来自 Azure 服务(如事件中心、服务总线等)的事件来触发您的函数。
您还可以使用 maven 插件com.microsoft.azure:azure-functions-maven-plugin
将函数部署到 azure 函数,可以通过将以下内容添加到您的 pom.xml 中来配置 maven 插件
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>1.22.0</version>
<configuration>
<appName>scf-samples</appName>
<resourceGroup>java-functions-group</resourceGroup>
<region>westus</region>
<appServicePlanName>java-functions-app-service-plan</appServicePlanName>
<pricingTier>EP1</pricingTier>
<hostJson>${project.basedir}/src/main/resources/host.json</hostJson>
<runtime>
<os>linux</os>
<javaVersion>17</javaVersion>
</runtime>
<funcPort>7072</funcPort>
<appSettings>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
</appSettings>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
这将使您的 Azure Java 函数与 Spring Cloud Function 集成,并且您可以利用 Spring Cloud Function 的强大功能,例如函数组合、基于 POJO 的开发等等。
有关更多信息,请查看更新的Azure 适配器参考文档,以及各种示例可以在此处找到。
任何使用 FunctionInvoker 的现有应用程序都可以轻松地转换为新的 DI Azure 函数集成样式。
例如,让我们转换以下使用遗留 FunctionInvoker 样式的示例应用程序。
Spring Boot 定义引导应用程序和一个名为 uppercase 的 Spring Cloud 函数
import java.util.Map;
import java.util.function.Function;
import com.microsoft.azure.functions.ExecutionContext;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.function.json.JsonMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
@SpringBootApplication
public class Config {
public static void main(String[] args) throws Exception {
SpringApplication.run(Config.class, args);
}
@Bean
public Function<Message<String>, String> uppercase(JsonMapper mapper) {
return message -> {
String value = message.getPayload();
try {
Map<String, String> map = mapper.fromJson(value, Map.class);
if(map != null)
map.forEach((k, v) -> map.put(k, v != null ? v.toUpperCase() : null));
return mapper.toString(map);
} catch (Exception e) {
e.printStackTrace();
return ("Function error: - bad request");
}
};
}
}
使用 uppercase 函数作为 Azure 函数的 FunctionInvoker 将如下所示
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import java.util.Optional;
import org.springframework.cloud.function.adapter.azure.FunctionInvoker;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
public class UppercaseHandler extends FunctionInvoker<Message<String>, String> {
@FunctionName("uppercase")
public String execute(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context
) {
context.getLogger().warning("Using Java (" + System.getProperty("java.version") + ")");
Message<String> message = MessageBuilder.withPayload(request.getBody().get())
.copyHeaders(request.getHeaders()).build();
return handleRequest(message, context);
}
}
请注意,按照约定,@FunctionName
必须与 @Bean 函数名称(在 Config 类中)匹配。
重构 UppercaseHandler 类以替换遗留的 FunctionInvoker 并使用 DI 非常简单,如下所示
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import java.util.Optional;
import org.springframework.cloud.function.adapter.azure.FunctionInvoker;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
@Component
public class UppercaseHandler {
@Autowired
private Function<Message<String>, String> uppercase;
@FunctionName("uppercase")
public String execute(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context
) {
context.getLogger().warning("Using Java (" + System.getProperty("java.version") + ")");
Message<String> message = MessageBuilder.withPayload(request.getBody().get())
.copyHeaders(request.getHeaders()).build();
return uppercase.apply(message);
}
}
@Component
类注释。FunctionInvoke
类继承。handleRequest
方法调用。现在您可以构建和部署您的应用程序了。