Azure Functions Java 开发人员指南Azure Functions Java developer guide

本指南包含有助于成功使用 Java 开发 Azure Functions 的详细信息。This guide contains detailed information to help you succeed developing Azure Functions using Java.

作为 Java 开发人员,如果不熟悉 Azure Functions,请考虑先阅读以下文章之一:As a Java developer, if you're new to Azure Functions, please consider first reading one of the following articles:

入门Getting started 概念Concepts

Java 函数基础知识Java function basics

Java 函数是一个 public 方法,使用注释 @FunctionName 进行修饰。A Java function is a public method, decorated with the annotation @FunctionName. 此方法定义了 Java 函数的输入,在特定包中必须唯一。This method defines the entry for a Java function, and must be unique in a particular package. 包可以有多个类,这些类具有使用 @FunctionName 进行批注的多个公共方法。The package can have multiple classes with multiple public methods annotated with @FunctionName. 单个包在 Azure 中部署到函数应用。A single package is deployed to a function app in Azure. 在 Azure 中运行时,函数应用可为各个 Java 函数提供部署、执行和管理上下文。When running in Azure, the function app provides the deployment, execution, and management context for your individual Java functions.

编程模型Programming model

触发器和绑定是 Azure Functions 的基本概念。The concepts of triggers and bindings are fundamental to Azure Functions. 触发器启动代码的执行。Triggers start the execution of your code. 绑定可让你向函数传递数据以及从函数返回数据,而无需编写自定义的数据访问代码。Bindings give you a way to pass data to and return data from a function, without having to write custom data access code.

创建 Java 函数Create Java functions

为了更轻松地创建 Java 函数,有一些基于 Maven 的工具和原型使用预定义的 Java 模板来帮助你创建包含特定函数触发器的项目。To make it easier to create Java functions, there are Maven-based tooling and archetypes that use predefined Java templates to help you create projects with a specific function trigger.

基于 Maven 的工具Maven-based tooling

以下开发人员环境具有 Azure Functions 工具,可用于创建 Java 函数项目:The following developer environments have Azure Functions tooling that lets you create Java function projects:

以上文章链接介绍了如何使用所选的 IDE 创建前几个函数。The article links above show you how to create your first functions using your IDE of choice.

创建项目基架Project Scaffolding

如果更喜欢从终端进行命令行开发,那么要对基于 Java 的函数项目创建基架,最简单的方法是使用 Apache Maven 原型。If you prefer command line development from the Terminal, the simplest way to scaffold Java-based function projects is to use Apache Maven archetypes. 适用于 Azure Functions 的 Java Maven 原型发布在以下 groupId:artifactId 之下 Java Maven archetype for Azure Functions is published under the following groupId:artifactId:

以下命令使用此原型生成新的 Java 函数项目:The following command generates a new Java function project using this archetype:

mvn archetype:generate \ \

若要开始使用此原型,请参阅 Java 快速入门To get started using this archetype, see the Java quickstart.

文件夹结构Folder structure

下面是某个 Azure Functions Java 项目的文件夹结构:Here is the folder structure of an Azure Functions Java project:

 | - src
 | | - main
 | | | - java
 | | | | - FunctionApp
 | | | | | -
 | | | | | -
 | - target
 | | - azure-functions
 | | | - FunctionApp
 | | | | - FunctionApp.jar
 | | | | - host.json
 | | | | - MyFirstFunction
 | | | | | - function.json
 | | | | - MySecondFunction
 | | | | | - function.json
 | | | | - bin
 | | | | - lib
 | - pom.xml

可使用共享的 host.json 文件来配置函数应用。You can use a shared host.json file to configure the function app. 每个函数都有自己的代码文件 (.java) 和绑定配置文件 (function.json)。Each function has its own code file (.java) and binding configuration file (function.json).

可在项目中放置多个函数。You can put more than one function in a project. 不要将函数放入单独的 jar 中。Avoid putting your functions into separate jars. 目标目录中的 FunctionApp 是部署到 Azure 中的函数应用的内容。The FunctionApp in the target directory is what gets deployed to your function app in Azure.

触发器和注释Triggers and annotations

函数由触发器(例如 HTTP 请求、计时器或数据更新)调用。Functions are invoked by a trigger, such as an HTTP request, a timer, or an update to data. 函数需要处理该触发器和任何其他输入以生成一个或多个输出。Your function needs to process that trigger, and any other inputs, to produce one or more outputs.

使用* 包中附带的 Java 注释将输入和输出绑定到方法。Use the Java annotations included in the* package to bind input and outputs to your methods. 有关详细信息,请参阅 Java 参考文档For more information, see the Java reference docs.


必须在 local.settings.json 中配置一个 Azure 存储帐户,才能在本地运行 Azure Blob 存储、Azure 队列存储或 Azure 表存储触发器。You must configure an Azure Storage account in your local.settings.json to run Azure Blob storage, Azure Queue storage, or Azure Table storage triggers locally.


public class Function {
    public String echo(@HttpTrigger(name = "req", 
      methods = {HttpMethod.POST},  authLevel = AuthorizationLevel.ANONYMOUS) 
        String req, ExecutionContext context) {
        return String.format(req);

下面是 azure-functions-maven-plugin 生成的相应 function.jsonHere is the generated corresponding function.json by the azure-functions-maven-plugin:

  "scriptFile": "azure-functions-example.jar",
  "entryPoint": "com.example.Function.echo",
  "bindings": [
      "type": "httpTrigger",
      "name": "req",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": [ "post" ]
      "type": "http",
      "name": "$return",
      "direction": "out"

Java 版本Java versions

创建函数应用(用于在 Azure 中运行函数)时使用的 Java 版本在 pom.xml 文件中指定。The version of Java used when creating the function app on which functions runs in Azure is specified in the pom.xml file. Maven 原型当前为 Java 8(可以在发布之前进行更改)生成 pom.xml。The Maven archetype currently generates a pom.xml for Java 8, which you can change before publishing. pom.xml 中的 Java 版本应该与在本地对其开发和测试应用的版本相匹配。The Java version in pom.xml should match the version on which you have locally developed and tested your app.

支持的版本Supported versions

下表按操作系统显示了 Functions 运行时的每个主版本当前支持的 Java 版本:The following table shows current supported Java versions for each major version of the Functions runtime, by operating system:

Functions 版本Functions version Java 版本 (Windows)Java versions (Windows) Java 版本 (Linux)Java versions (Linux)
3.x3.x 1111
2.x2.x 88 不适用n/a

除非为部署指定 Java 版本,否则在部署到 Azure 期间,Maven 原型默认为 Java 8。Unless you specify a Java version for your deployment, the Maven archetype defaults to Java 8 during deployment to Azure.

指定部署版本Specify the deployment version

可以使用 -DjavaVersion 参数来控制 Maven 原型的目标 Java 版本。You can control the version of Java targeted by the Maven archetype by using the -DjavaVersion parameter. 该参数的值可以是 811The value of this parameter can be either 8 or 11.

Maven 原型生成面向指定 Java 版本的 pom.xml。The Maven archetype generates a pom.xml that targets the specified Java version. pom.xml 文件中的以下元素指示要使用的 Java 版本:The following elements in pom.xml indicate the Java version to use:

元素Element Java 8 值Java 8 value Java 11 值Java 11 value 描述Description
Java.version 1.81.8 1111 maven-compiler-plugin 使用的 Java 版本。Version of Java used by the maven-compiler-plugin.
JavaVersion 88 1111 Azure 中的函数应用托管的 Java 版本。Java version hosted by the function app in Azure.

以下示例演示 pom.xml 文件的相关部分中用于 Java 8 的设置:The following examples show the settings for Java 8 in the relevant sections of the pom.xml file:




                        <!-- runtime os, could be windows, linux or docker-->
                        <!-- for docker function, please set the following parameters -->
                        <!-- <image>[hub-user/]repo-name[:tag]</image> -->
                        <!-- <serverId></serverId> -->
                        <!-- <registryUrl></registryUrl>  -->


必须将 JAVA_HOME 环境变量正确设置为在使用 Maven 编译代码期间使用的 JDK 目录。You must have the JAVA_HOME environment variable set correctly to the JDK directory that is used during code compiling using Maven. 确保 JDK 的版本至少与 Java.version 设置一样高。Make sure that the version of the JDK is at least as high as the Java.version setting.

指定部署操作系统Specify the deployment OS

Maven 还允许指定用于在 Azure 中运行函数应用的操作系统。Maven also lets you specify the operating system on which your function app runs in Azure. 使用 os 元素选择操作系统。Use the os element to choose the operating system.

元素Element WindowsWindows LinuxLinux DockerDocker
os windowswindows linuxlinux dockerdocker

以下示例显示了 pom.xml 文件的 runtime 部分中的操作系统设置:The following example shows the operating system setting in the runtime section of the pom.xml file:

                        <!-- runtime os, could be windows, linux or docker-->
                        <!-- for docker function, please set the following parameters -->
                        <!-- <image>[hub-user/]repo-name[:tag]</image> -->
                        <!-- <serverId></serverId> -->
                        <!-- <registryUrl></registryUrl>  -->

JDK 运行时可用性和支持JDK runtime availability and support

若要进行本地 Java 函数应用开发,请从 Azul Systems 下载并使用相应的适用于 Azure 的 Azul Zulu Enterprise Java JDK。For local development of Java function apps, download and use the appropriate Azul Zulu Enterprise for Azure Java JDKs from Azul Systems. 将函数应用部署到云时,Azure Functions 使用 Azul Java JDK 运行时。Azure Functions uses an Azul Java JDK runtime when you deploy your function app to the cloud.

对于 JDK 和函数应用的问题,Azure 支持可通过限定的支持计划获得。Azure support for issues with the JDKs and function apps is available with a qualified support plan.

自定义 JVMCustomize JVM

在 Functions 中可以自定义用于运行 Java 函数的 Java 虚拟机 (JVM)。Functions lets you customize the Java virtual machine (JVM) used to run your Java functions. 默认使用以下 JVM 选项The following JVM options are used by default:

  • -XX:+TieredCompilation
  • -XX:TieredStopAtLevel=1
  • -noverify
  • -jar

可在名为 JAVA_OPTS 的应用设置中提供其他参数。You can provide additional arguments in an app setting named JAVA_OPTS. 可在 Azure 门户或 Azure CLI 中将应用设置添加到部署给 Azure 的函数应用。You can add app settings to your function app deployed to Azure in the Azure portal or the Azure CLI.


在消耗计划中,还必须添加值为 0 的 WEBSITE_USE_PLACEHOLDER 设置,才能使自定义操作生效。In the Consumption plan, you must also add the WEBSITE_USE_PLACEHOLDER setting with a value of 0 for the customization to work. 此设置将增加 Java 函数的冷启动时间。This setting does increase the cold start times for Java functions.

Azure 门户Azure portal

Azure 门户中,使用“应用程序设置”选项卡添加 JAVA_OPTS 设置。In the Azure portal, use the Application Settings tab to add the JAVA_OPTS setting.

Azure CLIAzure CLI

可使用 az functionapp config appsettings set 命令设置 JAVA_OPTS,如下例中所示:You can use the az functionapp config appsettings set command to set JAVA_OPTS, as in the following example:

az functionapp config appsettings set \
    --settings "JAVA_OPTS=-Djava.awt.headless=true" \
    --name <APP_NAME> --resource-group <RESOURCE_GROUP>

此示例将启用无外设模式。This example enables headless mode. <APP_NAME> 替换为函数应用的名称,将 <RESOURCE_GROUP> 替换为资源组。Replace <APP_NAME> with the name of your function app, and <RESOURCE_GROUP> with the resource group.

第三方库Third-party libraries

Azure Functions 支持使用第三方库。Azure Functions supports the use of third-party libraries. 默认情况下,项目 pom.xml 文件中指定的所有依赖项将在 mvn package 目标期间自动进行绑定。By default, all dependencies specified in your project pom.xml file are automatically bundled during the mvn package goal. 对于未在 pom.xml 文件中指定为依赖项的库,请将它们放在函数根目录的 lib 目录中。For libraries not specified as dependencies in the pom.xml file, place them in a lib directory in the function's root directory. 放置在 lib 目录中的依赖项将在运行时添加到系统类加载器中。Dependencies placed in the lib directory are added to the system class loader at runtime.

默认情况下,类路径上提供了 依赖项,不需要将其包含在 lib 目录中。The dependency is provided on the classpath by default, and doesn't need to be included in the lib directory. 此外,azure-functions-java-worker 会将此处列出的依赖项添加到类路径。Also, azure-functions-java-worker adds dependencies listed here to the classpath.

数据类型支持Data type support

可以使用无格式普通 Java 对象 (POJO)、azure-functions-java-library 中定义的类型或字符串、整数等基元数据类型绑定到输入或输出绑定。You can use Plain old Java objects (POJOs), types defined in azure-functions-java-library, or primitive data types such as String and Integer to bind to input or output bindings.


azure-functions-java-worker 使用 gson 库将输入数据转换为 POJO。For converting input data to POJO, azure-functions-java-worker uses the gson library. 用作函数输入的 POJO 类型应是 publicPOJO types used as inputs to functions should be public.

Binary dataBinary data

通过将 function.json 中的 dataType 字段设置为 binary,将二进制输入或输出绑定到 byte[]Bind binary inputs or outputs to byte[], by setting the dataType field in your function.json to binary:

     public void blobTrigger(
        @BlobTrigger(name = "content", path = "myblob/{fileName}", dataType = "binary") byte[] content,
        @BindingName("fileName") String fileName,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Size: " + content.length + " Bytes");

如果需要 null 值,请使用 Optional<T>If you expect null values, use Optional<T>.


输入和输出绑定提供从代码内连接到数据的声明性方式。Input and output bindings provide a declarative way to connect to data from within your code. 一个函数可以有多个输入和输出绑定。A function can have multiple input and output bindings.

输入绑定示例Input binding example

package com.example;


public class Function {
    public static String echo(
        @HttpTrigger(name = "req", methods = { HttpMethod.PUT }, authLevel = AuthorizationLevel.ANONYMOUS, route = "items/{id}") String inputReq,
        @TableInput(name = "item", tableName = "items", partitionKey = "Example", rowKey = "{id}", connection = "AzureWebJobsStorage") TestInputData inputData,
        @TableOutput(name = "myOutputTable", tableName = "Person", connection = "AzureWebJobsStorage") OutputBinding<Person> testOutputData
    ) {
        testOutputData.setValue(new Person(httpbody + "Partition", httpbody + "Row", httpbody + "Name"));
        return "Hello, " + inputReq + " and " + inputData.getKey() + ".";

    public static class TestInputData {
        public String getKey() { return this.RowKey; }
        private String RowKey;
    public static class Person {
        public String PartitionKey;
        public String RowKey;
        public String Name;

        public Person(String p, String r, String n) {
            this.PartitionKey = p;
            this.RowKey = r;
            this.Name = n;

结合 HTTP 请求调用此函数。You invoke this function with an HTTP request.

  • String 的形式为参数 inputReq 传递 HTTP 请求有效负载。HTTP request payload is passed as a String for the argument inputReq.
  • 从表存储中检索一个项,并将其作为 TestInputData 传递给参数 inputDataOne entry is retrieved from Table storage, and is passed as TestInputData to the argument inputData.

若要接收一批输入,可绑定到 String[]POJO[]List<String>List<POJO>To receive a batch of inputs, you can bind to String[], POJO[], List<String>, or List<POJO>.

    public void processIotMessages(
        @EventHubTrigger(name = "message", eventHubName = "%AzureWebJobsEventHubPath%", connection = "AzureWebJobsEventHubSender", cardinality = Cardinality.MANY) List<TestEventData> messages,
        final ExecutionContext context)
        context.getLogger().info("Java Event Hub trigger received messages. Batch size: " + messages.size());
    public class TestEventData {
    public String id;

每当配置的事件中心内出现新数据时,就会触发此函数。This function gets triggered whenever there is new data in the configured event hub. 由于 cardinality 设置为 MANY,该函数将从事件中心接收一批消息。Because the cardinality is set to MANY, the function receives a batch of messages from the event hub. 来自事件中心的 EventData 将转换为函数执行的 TestEventDataEventData from event hub gets converted to TestEventData for the function execution.

输出绑定示例Output binding example

可以使用 $return 将输出绑定绑定到返回值。You can bind an output binding to the return value by using $return.

package com.example;


public class Function {
    @BlobOutput(name = "$return", path = "samples-output-java/{name}")
    public static String copy(@BlobTrigger(name = "blob", path = "samples-input-java/{name}") String content) {
        return content;

如果有多个输出绑定,请只使用其中一个绑定的返回值。If there are multiple output bindings, use the return value for only one of them.

若要发送多个输出值,请使用 azure-functions-java-library 包中定义的 OutputBinding<T>To send multiple output values, use OutputBinding<T> defined in the azure-functions-java-library package.

    public HttpResponseMessage QueueOutputPOJOList(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
            HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @QueueOutput(name = "itemsOut", queueName = "test-output-java-pojo", connection = "AzureWebJobsStorage") OutputBinding<List<TestData>> itemsOut, 
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");
        String query = request.getQueryParameters().get("queueMessageId");
        String queueMessageId = request.getBody().orElse(query);
        itemsOut.setValue(new ArrayList<TestData>());
        if (queueMessageId != null) {
            TestData testData1 = new TestData();
   = "msg1"+queueMessageId;
            TestData testData2 = new TestData();
   = "msg2"+queueMessageId;


            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + queueMessageId).build();
        } else {
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Did not find expected items in CosmosDB input list").build();

     public static class TestData {
        public String id;

针对 HttpRequest 调用此函数。You invoke this function on an HttpRequest. 它会将多个值写入到队列存储。It writes multiple values to Queue storage.

HttpRequestMessage 和 HttpResponseMessageHttpRequestMessage and HttpResponseMessage

这些对象在 azure-functions-java-library 中定义。These are defined in azure-functions-java-library. 它们是与 HttpTrigger 函数配合使用的帮助器类型。They are helper types to work with HttpTrigger functions.

专用类型Specialized type 目标Target 典型用途Typical usage
HttpRequestMessage<T> HTTP 触发器HTTP Trigger 获取方法、标头或查询Gets method, headers, or queries
HttpResponseMessage HTTP 输出绑定HTTP Output Binding 返回除 200 以外的状态Returns status other than 200


少量的触发器会连同输入数据一起发送触发器元数据Few triggers send trigger metadata along with input data. 可使用注释 @BindingName 绑定到触发器元数据。You can use annotation @BindingName to bind to trigger metadata.

package com.example;

import java.util.Optional;

public class Function {
    public static String metadata(
        @HttpTrigger(name = "req", methods = { HttpMethod.GET, HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) Optional<String> body,
        @BindingName("name") String queryValue
    ) {
        return body.orElse(queryValue);

在前面的示例中,queryValue 绑定到 HTTP 请求 URL http://{}/api/metadata?name=test 中的查询字符串参数 nameIn the preceding example, the queryValue is bound to the query string parameter name in the HTTP request URL, http://{}/api/metadata?name=test. 下面是另一个示例,它展示了如何从队列触发器元数据绑定到 IdHere's another example, showing how to bind to Id from queue trigger metadata.

    public void QueueTriggerMetadata(
        @QueueTrigger(name = "message", queueName = "test-input-java-metadata", connection = "AzureWebJobsStorage") String message,@BindingName("Id") String metadataId,
        @QueueOutput(name = "output", queueName = "test-output-java-metadata", connection = "AzureWebJobsStorage") OutputBinding<TestData> output,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Queue trigger function processed a message: " + message + " with metadaId:" + metadataId );
        TestData testData = new TestData(); = metadataId;


在注释中提供的名称需与元数据属性相匹配。The name provided in the annotation needs to match the metadata property.

执行上下文Execution context

azure-functions-java-library 中定义的 ExecutionContext 包含用来与 Functions 运行时通信的帮助器方法。ExecutionContext, defined in the azure-functions-java-library, contains helper methods to communicate with the functions runtime. 有关详细信息,请参阅 ExecutionContext 参考文章For more information, see the ExecutionContext reference article.


使用 ExecutionContext 中定义的 getLogger 从函数代码写入日志。Use getLogger, defined in ExecutionContext, to write logs from function code.



public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        if (req.isEmpty()) {
            context.getLogger().warning("Empty request body received by function " + context.getFunctionName() + " with invocation " + context.getInvocationId());
        return String.format(req);

查看日志和跟踪View logs and trace

可以使用 Azure CLI 来流式传输 Java stdout 和 stderr 日志记录以及其他应用程序日志记录。You can use the Azure CLI to stream Java stdout and stderr logging, as well as other application logging.

下面说明了如何使用 Azure CLI 将函数应用配置为写入应用程序日志:Here's how to configure your function app to write application logging by using the Azure CLI:

az webapp log config --name functionname --resource-group myResourceGroup --application-logging true

若要使用 Azure CLI 流式传输函数应用的日志记录输出,请打开新的命令行提示符、Bash 或终端会话,并输入以下命令:To stream logging output for your function app by using the Azure CLI, open a new command prompt, Bash, or Terminal session, and enter the following command:

az webapp log tail --name webappname --resource-group myResourceGroup

az webapp log tail 命令可使用 --provider 选项筛选输出。The az webapp log tail command has options to filter output by using the --provider option.

若要使用 Azure CLI 下载单个 ZIP 文件形式的日志文件,请打开新的命令提示符、Bash 或终端会话,并输入以下命令:To download the log files as a single ZIP file by using the Azure CLI, open a new command prompt, Bash, or Terminal session, and enter the following command:

az webapp log download --resource-group resourcegroupname --name functionappname

运行此命令之前,必须已在 Azure 门户或 Azure CLI 中启用了文件系统日志记录。You must have enabled file system logging in the Azure portal or the Azure CLI before running this command.

环境变量Environment variables

在 Functions 中,服务连接字符串等应用设置在执行过程中将公开为环境变量。In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. 可使用 System.getenv("AzureWebJobsStorage") 访问这些设置。You can access these settings by using, System.getenv("AzureWebJobsStorage").

以下示例获取了应用程序设置,其中键名为 myAppSettingThe following example gets the application setting, with the key named myAppSetting:

public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        context.getLogger().info("My app setting value: "+ System.getenv("myAppSetting"));
        return String.format(req);


对于优化的冷启动体验,AppSetting FUNCTIONS_EXTENSION_VERSION 的值应为 ~2 或 ~3。The value of AppSetting FUNCTIONS_EXTENSION_VERSION should be ~2 or ~3 for an optimized cold start experience.

后续步骤Next steps

有关 Azure Functions Java 开发的详细信息,请参阅以下资源:For more information about Azure Functions Java development, see the following resources: