Příručka pro vývojáře v Javě pro Azure Functions

Tato příručka obsahuje podrobné informace, které vám pomůžou s vývojem azure Functions pomocí Javy.

Pokud s Azure Functions teprve začínáte, zvažte jako vývojáře v Javě nejprve jeden z následujících článků:

Začínáme Koncepty Scénáře/ukázky

Základy funkcí v Javě

Funkce Java je public metoda, zdobená poznámkami @FunctionName. Tato metoda definuje položku pro funkci Java a musí být jedinečná v konkrétním balíčku. Balíček může mít více tříd s více veřejnými metodami anotacemi s @FunctionName. Do aplikace funkcí v Azure se nasadí jeden balíček. Aplikace funkcí v Azure poskytuje kontext nasazení, spouštění a správy pro jednotlivé funkce Javy.

Programovací model

Koncepty triggerů a vazeb jsou pro Azure Functions zásadní. Triggery spustí spuštění kódu. Vazby poskytují způsob, jak předávat data do funkce a vracet je, aniž byste museli psát vlastní přístupový kód dat.

Vytváření funkcí v Javě

Aby bylo možné snadněji vytvářet funkce v Javě, existují nástroje a archetypy Mavenu, které používají předdefinované šablony Javy, které vám pomůžou vytvářet projekty s konkrétní aktivační událostí funkce.

Nástroje založené na Mavenu

Následující vývojářská prostředí mají nástroje Azure Functions, které umožňují vytvářet projekty funkcí v Javě:

V těchto článcích se dozvíte, jak vytvořit první funkce pomocí zvoleného integrovaného vývojového prostředí (IDE).

Generování uživatelského rozhraní projektu

Pokud dáváte přednost vývoji z příkazového řádku z terminálu, nejjednodušší způsob, jak vygenerovat projekty funkcí založené na Javě, je použít Apache Maven archetypy. Archetyp Java Maven pro Azure Functions se publikuje pod následujícím typem groupId:artifactId: com.microsoft.azure:azure-functions-archetype.

Následující příkaz vygeneruje nový projekt funkcí Java pomocí tohoto archetypu:

mvn archetype:generate \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype

Pokud chcete začít používat tento archetyp, přečtěte si rychlý start pro Javu.

Struktura složek

Tady je struktura složek projektu Azure Functions v Javě:

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

Ke konfiguraci aplikace funkcí můžete použít sdílený soubor host.json . Každá funkce má vlastní soubor kódu (.java) a konfigurační soubor vazby (function.json).

Do projektu můžete vložit více než jednu funkci. Vyhněte se vkládání funkcí do samostatných jar. V FunctionApp cílovém adresáři se nasadí do vaší aplikace funkcí v Azure.

Triggery a poznámky

Funkce jsou vyvolány triggerem, jako je požadavek HTTP, časovač nebo aktualizace dat. Vaše funkce potřebuje zpracovat tento trigger a všechny další vstupy, aby se vytvořil jeden nebo více výstupů.

Pomocí poznámek Java obsažených v balíčku com.microsoft.azure.functions.annotation.* můžete svázat vstupy a výstupy s vašimi metodami. Další informace najdete v referenční dokumentaci k Javě.

Důležité

Ve svém local.settings.json musíte nakonfigurovat účet služby Azure Storage tak, aby spouštěl triggery Azure Blob Storage, Azure Queue Storage nebo Azure Table Storage místně.

Příklad:

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

Tady je vygenerovaný modul function.jsonplug-in azure-functions-maven-plugin:

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

Verze Javy

Verze Javy, na které vaše aplikace běží v Azure, se zadává v souboru pom.xml. Archetyp Maven v současné době generuje pom.xml pro Javu 8, kterou můžete před publikováním změnit. Verze Javy v pom.xml by měla odpovídat verzi, na které jste místně vyvinuli a otestovali aplikaci.

Podporované verze

Následující tabulka uvádí aktuální podporované verze Javy pro každou hlavní verzi modulu runtime Functions podle operačního systému:

Verze služby Functions Verze Javy (Windows) Verze Javy (Linux)
4.x 17
11
8
21 (Preview)
17
11
8
3.x 11
8
11
8
2.x 8 Není k dispozici

Pokud pro nasazení nezadáte verzi Javy, archetyp Maven se během nasazování do Azure nastaví na Javu 8.

Určení verze nasazení

Verzi Javy, na kterou cílí archetyp Maven, můžete řídit pomocí parametru -DjavaVersion . Hodnota tohoto parametru může být buď 8, 1117 nebo 21.

Archetyp Maven vygeneruje pom.xml, který cílí na zadanou verzi Javy. Následující prvky v pom.xml označují verzi Javy, která se má použít:

Element (Prvek) Hodnota Java 8 Hodnota Java 11 Hodnota Java 17 Hodnota Java 21 (Preview, Linux) Popis
Java.version 1.8 11 17 21 Verze Javy používaná modulem plug-in maven-compiler-plugin
JavaVersion 8 11 17 21 Verze Javy hostovaná aplikací funkcí v Azure

Následující příklady ukazují nastavení Javy 8 v příslušných částech souboru pom.xml:

Java.version

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <azure.functions.maven.plugin.version>1.6.0</azure.functions.maven.plugin.version>
    <azure.functions.java.library.version>1.3.1</azure.functions.java.library.version>
    <functionAppName>fabrikam-functions-20200718015742191</functionAppName>
    <stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
</properties>

JavaVersion

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

Důležité

Musíte mít správně nastavenou proměnnou prostředí JAVA_HOME na adresář JDK, který se používá při kompilaci kódu pomocí Mavenu. Ujistěte se, že je verze sady JDK alespoň tak vysoká jako Java.version nastavení.

Určení operačního systému nasazení

Maven také umožňuje určit operační systém, na kterém běží vaše aplikace funkcí v Azure. os Pomocí prvku zvolte operační systém.

Element (Prvek) Windows Linux Docker
os windows linux docker

Následující příklad ukazuje nastavení operačního systému v runtime části souboru pom.xml:

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

Dostupnost a podpora modulu runtime JDK

Buildy OpenJDK od Microsoftu a Adoptium jsou poskytované a podporované ve funkcích pro Javu 8 (Adoptium), Javě 11, 17 a 21 (MSFT). Tyto binární soubory jsou poskytovány jako distribuce OpenJDK pro Azure bez nákladů na více platforem a připravené pro produkční prostředí. Obsahuje všechny komponenty pro vytváření a spouštění aplikací Java SE.

Pro místní vývoj nebo testování si můžete zdarma stáhnout build OpenJDK nebo Adoptium Temurin . podpora Azure pro problémy se sadami JDK a aplikacemi funkcí jsou k dispozici s kvalifikovaným plánem podpory.

Pokud chcete ve své aplikaci Funkcí dál používat binární soubory Zulu pro Azure, nakonfigurujte aplikaci odpovídajícím způsobem. Binární soubory Azul můžete dál používat pro svůj web. Všechny opravy zabezpečení nebo vylepšení jsou však k dispozici pouze v nových verzích sady OpenJDK. Z tohoto důvodu byste tuto konfiguraci měli nakonec odebrat, aby vaše aplikace používaly nejnovější dostupnou verzi Javy.

Přizpůsobení prostředí JVM

Funkce umožňují přizpůsobit virtuální počítač Java (JVM) používaný ke spouštění funkcí Javy. Ve výchozím nastavení se používají následující možnosti prostředí JVM:

  • -XX:+TieredCompilation
  • -XX:TieredStopAtLevel=1
  • -noverify
  • -Djava.net.preferIPv4Stack=true
  • -jar

Pro JVM můžete zadat další argumenty pomocí jednoho z následujících nastavení aplikace v závislosti na typu plánu:

Typ plánu Název nastavení Komentář
Plán Consumption languageWorkers__java__arguments Toto nastavení zvyšuje dobu studeného spuštění funkcí Java spuštěných v plánu Consumption.
Plán Premium
Vyhrazený plán
JAVA_OPTS

Následující části ukazují, jak tato nastavení přidat. Další informace o práci s nastavením aplikace najdete v části Práce s nastavením aplikace.

portál Azure

Na webu Azure Portal použijte kartu Nastavení aplikace a přidejte nastavenílanguageWorkers__java__arguments.JAVA_OPTS

Azure CLI

K přidání těchto nastavení můžete použít příkaz az functionapp config appsettings set , jak je znázorněno v následujícím příkladu -Djava.awt.headless=true možnosti:

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

Tento příklad umožňuje bezobsadový režim. Nahraďte <APP_NAME> názvem vaší aplikace funkcí a <RESOURCE_GROUP> skupinou prostředků.

Knihovny třetích stran

Azure Functions podporuje použití knihoven třetích stran. Ve výchozím nastavení se všechny závislosti zadané v souboru projektu pom.xml automaticky sbalí během mvn package cíle. Pro knihovny, které nejsou zadané jako závislosti v pom.xml souboru, je umístěte do lib adresáře v kořenovém adresáři funkce. Závislosti umístěné v lib adresáři se přidají do zavaděče třídy systému za běhu.

Závislost com.microsoft.azure.functions:azure-functions-java-library je ve výchozím nastavení poskytována v cestě k třídě a není nutné ji zahrnout do lib adresáře. Azure-functions-java-worker také přidá do cesty ke třídě závislosti uvedené tady.

Podpora datových typů

K vytvoření vazby na vstupní nebo výstupní vazby můžete použít prosté staré objekty Jazyka Java (POJOs), typy definované v azure-functions-java-librarynebo primitivní datové typy, jako je String a Integer.

POJOs

Pro převod vstupních dat na POJO používá azure-functions-java-worker knihovnu gson . Typy POJO používané jako vstupy funkcí by měly být public.

Binární data

Vytvořte vazbu s binárními vstupy nebo výstupy byte[]tak, že v function.json nastavíte dataType pole na binary:

   @FunctionName("BlobTrigger")
    @StorageAccount("AzureWebJobsStorage")
     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");
    }

Pokud očekáváte hodnoty null, použijte Optional<T>.

Vazby

Vstupní a výstupní vazby poskytují deklarativní způsob připojení k datům z vašeho kódu. Funkce může mít více vstupních a výstupních vazeb.

Příklad vstupní vazby

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("echo")
    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;
        }
    }
}

Tuto funkci vyvoláte pomocí požadavku HTTP.

  • Datová část požadavku HTTP se předává jako String argument inputReq.
  • Jedna položka se načte ze služby Table Storage a předá se jako TestInputData argument inputData.

Chcete-li přijmout dávku vstupů, můžete vytvořit vazbu na String[], POJO[], List<String>nebo List<POJO>.

@FunctionName("ProcessIotMessages")
    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;
}

Tato funkce se aktivuje vždy, když v nakonfigurovaném centru událostí existují nová data. Protože je nastavena cardinality na MANY, funkce obdrží dávku zpráv z centra událostí. EventData z centra událostí se převede na TestEventData spuštění funkce.

Příklad výstupní vazby

Výstupní vazbu můžete s návratovou hodnotou svázat pomocí .$return

package com.example;

import com.microsoft.azure.functions.annotation.*;

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

Pokud existuje více výstupních vazeb, použijte vrácenou hodnotu pouze pro jednu z nich.

Pokud chcete odeslat více výstupních hodnot, použijte OutputBinding<T> definovaný v azure-functions-java-library balíčku.

@FunctionName("QueueOutputPOJOList")
    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();
            testData1.id = "msg1"+queueMessageId;
            TestData testData2 = new TestData();
            testData2.id = "msg2"+queueMessageId;

            itemsOut.getValue().add(testData1);
            itemsOut.getValue().add(testData2);

            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;
    }

Tuto funkci vyvoláte u objektu HttpRequest . Zapíše více hodnot do služby Queue Storage.

HttpRequestMessage a HttpResponseMessage

Ty jsou definovány v azure-functions-java-library. Jedná se o pomocné typy pro práci s funkcemi HttpTriggeru.

Specializovaný typ Cíl Typické použití
HttpRequestMessage<T> Trigger HTTP Získá metody, hlavičky nebo dotazy.
HttpResponseMessage Výstupní vazba HTTP Vrátí jiný stav než 200.

Metadata

Několik triggerů odesílá metadata triggeru spolu se vstupními daty. Poznámku @BindingName můžete použít k vytvoření vazby na aktivační metadata.

package com.example;

import java.util.Optional;
import com.microsoft.azure.functions.annotation.*;


public class Function {
    @FunctionName("metadata")
    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);
    }
}

V předchozím příkladu queryValue je vázán na parametr name řetězce dotazu v adrese URL požadavku HTTP , http://{example.host}/api/metadata?name=test. Tady je další příklad, který ukazuje, jak vytvořit vazbu na Id metadata triggeru fronty.

 @FunctionName("QueueTriggerMetadata")
    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();
        testData.id = metadataId;
        output.setValue(testData);
    }

Poznámka:

Název zadaný v poznámce musí odpovídat vlastnosti metadat.

Kontext spuštění

ExecutionContext, definované v nástroji azure-functions-java-library, obsahuje pomocné metody pro komunikaci s modulem runtime funkcí. Další informace najdete v referenčním článku ExecutionContext.

Logger

K zápisu protokolů z kódu funkce použijte getLogger, definovaný v ExecutionContext.

Příklad:


import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

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);
    }
}

Zobrazení protokolů a trasování

Pomocí Azure CLI můžete streamovat protokolování stdout Java a stderr a další protokolování aplikace.

Tady je postup konfigurace aplikace funkcí pro zápis protokolování aplikace pomocí Azure CLI:

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

Pokud chcete streamovat výstup protokolování pro vaši aplikaci funkcí pomocí Azure CLI, otevřete nový příkazový řádek, Bash nebo terminálovou relaci a zadejte následující příkaz:

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

Příkaz az webapp log tail nabízí možnosti filtrování výstupu pomocí této --provider možnosti.

Pokud chcete soubory protokolu stáhnout jako jeden soubor ZIP pomocí Azure CLI, otevřete nový příkazový řádek, Bash nebo terminálovou relaci a zadejte následující příkaz:

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

Před spuštěním tohoto příkazu musíte povolit protokolování systému souborů na webu Azure Portal nebo v Azure CLI.

Proměnné prostředí

Ve službě Functions se nastavení aplikace, jako jsou připojovací řetězec služby, zobrazují během provádění jako proměnné prostředí. K těmto nastavením se dostanete pomocí . System.getenv("AzureWebJobsStorage")

Následující příklad získá nastavení aplikace s klíčem s názvem 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);
    }
}

Použití injektáže závislostí ve službě Java Functions

Azure Functions Java podporuje vzor návrhu softwaru pro injektáž závislostí (DI), což je technika k dosažení inverze řízení (IoC) mezi třídami a jejich závislostmi. Azure Functions v Javě poskytuje hák pro integraci s oblíbenými architekturami injektáže závislostí ve vašich aplikacích Functions. Azure Functions Java SPI obsahuje rozhraní FunctionInstanceInjector. Implementací tohoto rozhraní můžete vrátit instanci třídy funkce a funkce budou vyvolány v této instanci. To poskytuje architektury, jako je Spring, Quarkus, Google Guice, Dagger atd. schopnost vytvořit instanci funkce a zaregistrovat ji do kontejneru IOC. To znamená, že tyto architektury injektáže závislostí můžete použít ke správě funkcí přirozeně.

Poznámka:

Microsoft Azure Functions Java SPI Types (azure-function-java-spi) je balíček, který obsahuje všechna rozhraní SPI pro třetí strany pro interakci s modulem runtime funkcí Microsoft Azure.

Injektor instance funkce pro injektáž závislostí

azure-function-java-spi obsahuje rozhraní FunctionInstanceInjector

package com.microsoft.azure.functions.spi.inject; 

/** 

 * The instance factory used by DI framework to initialize function instance. 

 * 

 * @since 1.0.0 

 */ 

public interface FunctionInstanceInjector { 

    /** 

     * This method is used by DI framework to initialize the function instance. This method takes in the customer class and returns 

     * an instance create by the DI framework, later customer functions will be invoked on this instance. 

     * @param functionClass the class that contains customer functions 

     * @param <T> customer functions class type 

     * @return the instance that will be invoked on by azure functions java worker 

     * @throws Exception any exception that is thrown by the DI framework during instance creation 

     */ 

    <T> T getInstance(Class<T> functionClass) throws Exception; 

} 

Další příklady, které používají FunctionInstanceInjector k integraci s architekturami injektáže závislostí, najdete v tomto úložišti.

Další kroky

Další informace o vývoji v Javě pro Azure Functions najdete v následujících zdrojích informací: