Utvecklarguide för Azure Functions Java
Den här guiden innehåller detaljerad information som hjälper dig att lyckas utveckla Azure Functions med Hjälp av Java.
Om du är nybörjare på Azure Functions som Java-utvecklare bör du överväga att först läsa någon av följande artiklar:
Komma igång | Begrepp | Scenarier/exempel |
---|---|---|
Grunderna i Java-funktionen
En Java-funktion är en public
metod som är dekorerad med anteckningen @FunctionName
. Den här metoden definierar posten för en Java-funktion och måste vara unik i ett visst paket. Paketet kan ha flera klasser med flera offentliga metoder kommenterade med @FunctionName
. Ett enda paket distribueras till en funktionsapp i Azure. I Azure tillhandahåller funktionsappen distributions-, körnings- och hanteringskontexten för dina enskilda Java-funktioner.
Programmeringsmodell
Begreppen utlösare och bindningar är grundläggande för Azure Functions. Utlösare startar körningen av koden. Bindningar ger dig ett sätt att skicka data till och returnera data från en funktion, utan att behöva skriva anpassad dataåtkomstkod.
Skapa Java-funktioner
För att göra det enklare att skapa Java-funktioner finns det Maven-baserade verktyg och arketyper som använder fördefinierade Java-mallar som hjälper dig att skapa projekt med en specifik funktionsutlösare.
Maven-baserade verktyg
Följande utvecklarmiljöer har Azure Functions-verktyg som gör att du kan skapa Java-funktionsprojekt:
De här artiklarna visar hur du skapar dina första funktioner med valfri IDE.
Projektställningar
Om du föredrar kommandoradsutveckling från terminalen är det enklaste sättet att skapa javabaserade funktionsprojekt att använda Apache Maven
arketyper. Java Maven-arketypen för Azure Functions publiceras under följande groupId:artifactId: com.microsoft.azure:azure-functions-archetype.
Följande kommando genererar ett nytt Java-funktionsprojekt med den här arketypen:
mvn archetype:generate \
-DarchetypeGroupId=com.microsoft.azure \
-DarchetypeArtifactId=azure-functions-archetype
Information om hur du kommer igång med den här arketypen finns i Snabbstart för Java.
Mappstrukturen
Här är mappstrukturen för ett Azure Functions Java-projekt:
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
Du kan använda en delad host.json-fil för att konfigurera funktionsappen. Varje funktion har en egen kodfil (.java) och en bindningskonfigurationsfil (function.json).
Du kan ha fler än en funktion i ett projekt. Placera dock inte dina funktioner i separata burkar. Det går inte att använda flera jar-filer i en enskild funktionsapp. I FunctionApp
målkatalogen är det som distribueras till din funktionsapp i Azure.
Utlösare och anteckningar
Funktioner anropas av en utlösare, till exempel en HTTP-begäran, en timer eller en uppdatering av data. Din funktion måste bearbeta utlösaren och andra indata för att generera en eller flera utdata.
Använd Java-anteckningarna som ingår i paketet com.microsoft.azure.functions.annotation.* för att binda indata och utdata till dina metoder. Mer information finns i Java-referensdokumenten.
Viktigt!
Du måste konfigurera ett Azure Storage-konto i din local.settings.json för att köra Azure Blob Storage, Azure Queue Storage eller Azure Table Storage-utlösare lokalt.
Exempel:
public class Function {
public String echo(@HttpTrigger(name = "req",
methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
String req, ExecutionContext context) {
return String.format(req);
}
}
Här är den genererade motsvarande function.json
av plugin-programmet azure-functions-maven-:
{
"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"
}
]
}
Java-versioner
Den version av Java som appen körs på i Azure anges i filen pom.xml. Maven-arketypen genererar för närvarande en pom.xml för Java 8, som du kan ändra innan du publicerar. Java-versionen i pom.xml ska matcha den version där du har utvecklat och testat appen lokalt.
Versioner som stöds
I följande tabell visas aktuella Java-versioner som stöds för varje huvudversion av Functions-körningen, efter operativsystem:
Funktionsversion | Java-versioner (Windows) | Java-versioner (Linux) |
---|---|---|
4.x | 17 11 8 |
21 (förhandsversion) 17 11 8 |
3.x | 11 8 |
11 8 |
2.x | 8 | saknas |
Såvida du inte anger en Java-version för distributionen är Maven-arketypen som standard Java 8 under distributionen till Azure.
Ange distributionsversionen
Du kan styra vilken version av Java som maven-arketypen riktar in sig på med hjälp av parametern -DjavaVersion
. Värdet för den här parametern kan vara antingen 8
, 17
11
eller 21
.
Maven-arketypen genererar en pom.xml som riktar sig mot den angivna Java-versionen. Följande element i pom.xml anger vilken Java-version som ska användas:
Element | Java 8-värde | Java 11-värde | Java 17-värde | Java 21-värde (förhandsversion, Linux) | beskrivning |
---|---|---|---|---|---|
Java.version |
1.8 | 11 | 17 | 21 | Version av Java som används av plugin-programmet maven-compiler-. |
JavaVersion |
8 | 11 | 17 | 21 | Java-version som hanteras av funktionsappen i Azure. |
I följande exempel visas inställningarna för Java 8 i relevanta avsnitt i pom.xml-filen:
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>
Viktigt!
Du måste ha JAVA_HOME miljövariabeln korrekt inställd på den JDK-katalog som används vid kodkompilering med Maven. Kontrollera att JDK-versionen är minst lika hög som inställningen Java.version
.
Ange distributionsoperativsystemet
Med Maven kan du också ange det operativsystem som funktionsappen körs på i Azure. Använd elementet os
för att välja operativsystemet.
Element | Windows | Linux | Docker |
---|---|---|---|
os |
windows |
linux |
docker |
I följande exempel visas operativsystemets inställning i runtime
avsnittet i filen 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>
Tillgänglighet och support för JDK-körning
Microsoft- och Adoptium-versioner av OpenJDK tillhandahålls och stöds på Functions for Java 8 (Adoptium), Java 11, 17 och 21 (MSFT). Dessa binärfiler tillhandahålls som en kostnadsfri distribution med flera plattformar och produktionsklara distributioner av OpenJDK för Azure. De innehåller alla komponenter för att skapa och köra Java SE-program.
För lokal utveckling eller testning kan du ladda ned Microsoft-versionen av OpenJDK eller Adoptium Temurin-binärfiler kostnadsfritt. Azure-stöd för problem med JDK:er och funktionsappar är tillgängligt med en kvalificerad supportplan.
Om du vill fortsätta använda binärfilerna Zulu för Azure i funktionsappen konfigurerar du appen i enlighet med detta. Du kan fortsätta att använda Azul-binärfilerna för din webbplats. Säkerhetskorrigeringar eller förbättringar är dock endast tillgängliga i nya versioner av OpenJDK. Därför bör du så småningom ta bort den här konfigurationen så att dina appar använder den senaste tillgängliga versionen av Java.
Anpassa JVM
Med Functions kan du anpassa den virtuella Java-dator (JVM) som används för att köra dina Java-funktioner. Följande JVM-alternativ används som standard:
-XX:+TieredCompilation
-XX:TieredStopAtLevel=1
-noverify
-Djava.net.preferIPv4Stack=true
-jar
Du kan ange andra argument för JVM genom att använda någon av följande programinställningar, beroende på plantyp:
Abonnemangstyp | Inställningsnamn | Kommentar |
---|---|---|
Förbrukningsplan | languageWorkers__java__arguments |
Den här inställningen ökar de kalla starttiderna för Java-funktioner som körs i en förbrukningsplan. |
Premium-plan Dedikerad plan |
JAVA_OPTS |
Följande avsnitt visar hur du lägger till de här inställningarna. Mer information om hur du arbetar med programinställningar finns i avsnittet Arbeta med programinställningar .
Azure Portal
I Azure-portalen använder du fliken Programinställningar för att lägga till antingen languageWorkers__java__arguments
inställningen eller JAVA_OPTS
.
Azure CLI
Du kan använda kommandot az functionapp config appsettings set för att lägga till de här inställningarna, som du ser i följande exempel för alternativet -Djava.awt.headless=true
:
az functionapp config appsettings set \
--settings "languageWorkers__java__arguments=-Djava.awt.headless=true" \
--name <APP_NAME> --resource-group <RESOURCE_GROUP>
Det här exemplet aktiverar huvudlöst läge. Ersätt <APP_NAME>
med namnet på funktionsappen och <RESOURCE_GROUP>
med resursgruppen.
Bibliotek från tredje part
Azure Functions stöder användning av bibliotek från tredje part. Som standard paketeras alla beroenden som anges i projektfilen pom.xml
automatiskt under mvn package
målet. För bibliotek som inte har angetts som beroenden pom.xml
i filen placerar du dem i en lib
katalog i funktionens rotkatalog. Beroenden som placeras i lib
katalogen läggs till i systemklassinläsaren vid körning.
Beroendet com.microsoft.azure.functions:azure-functions-java-library
tillhandahålls på klassökvägen som standard och behöver inte ingå i lib
katalogen. Dessutom lägger azure-functions-java-worker till beroenden som anges här i klassökvägen.
Stöd för datatyp
Du kan använda vanliga gamla Java-objekt (POJO), typer som definierats i azure-functions-java-library
, eller primitiva datatyper som Sträng och Heltal för att binda till indata- eller utdatabindningar.
POJO:er
För att konvertera indata till POJO använder azure-functions-java-worker gson-biblioteket. POJO-typer som används som indata till funktioner ska vara public
.
Binära data
Binda binära indata eller utdata till genom att byte[]
ange dataType
fältet i din function.json till 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");
}
Om du förväntar dig null-värden använder du Optional<T>
.
Bindningar
Indata- och utdatabindningar är ett deklarativt sätt att ansluta till data inifrån koden. En funktion kan ha flera in- och utdatabindningar.
Exempel på indatabindning
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;
}
}
}
Du anropar den här funktionen med en HTTP-begäran.
- Nyttolasten för HTTP-begäran skickas som en
String
för argumentetinputReq
. - En post hämtas från Table Storage och skickas
TestInputData
till argumentetinputData
.
Om du vill ta emot en batch med indata kan du binda till String[]
, POJO[]
, List<String>
eller 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;
}
Den här funktionen utlöses när det finns nya data i den konfigurerade händelsehubben. cardinality
Eftersom är inställt på MANY
tar funktionen emot en batch med meddelanden från händelsehubben. EventData
från händelsehubben konverteras till TestEventData
för funktionskörningen.
Exempel på utdatabindning
Du kan binda en utdatabindning till returvärdet med hjälp $return
av .
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;
}
}
Om det finns flera utdatabindningar använder du returvärdet för endast en av dem.
Om du vill skicka flera utdatavärden använder du OutputBinding<T>
definierat i azure-functions-java-library
paketet.
@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;
}
Du anropar den här funktionen på ett HttpRequest
objekt. Den skriver flera värden till Queue Storage.
HttpRequestMessage och HttpResponseMessage
Dessa definieras i azure-functions-java-library
. De är hjälptyper som fungerar med HttpTrigger-funktioner.
Specialiserad typ | Mål | Typisk användning |
---|---|---|
HttpRequestMessage<T> |
HTTP-utlösare | Hämtar metod, rubriker eller frågor |
HttpResponseMessage |
HTTP-utdatabindning | Returnerar annan status än 200 |
Metadata
Få utlösare skickar utlösarmetadata tillsammans med indata. Du kan använda anteckningar @BindingName
för att binda för att utlösa 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);
}
}
I föregående exempel är bundet queryValue
till frågesträngsparametern name
i HTTP-begärande-URL:en, http://{example.host}/api/metadata?name=test
. Här är ett annat exempel som visar hur du binder till Id
från metadata för köutlösare.
@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);
}
Kommentar
Namnet som anges i anteckningen måste matcha metadataegenskapen.
Körningskontext
ExecutionContext
, som definieras i azure-functions-java-library
, innehåller hjälpmetoder för att kommunicera med funktionskörningen. Mer information finns i referensartikeln ExecutionContext.
Logger
Använd getLogger
, definierat i ExecutionContext
, för att skriva loggar från funktionskoden.
Exempel:
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);
}
}
Visa loggar och spårning
Du kan använda Azure CLI för att strömma Java stdout- och stderr-loggning samt annan programloggning.
Så här konfigurerar du funktionsappen för att skriva programloggning med hjälp av Azure CLI:
az webapp log config --name functionname --resource-group myResourceGroup --application-logging true
Om du vill strömma loggningsutdata för funktionsappen med hjälp av Azure CLI öppnar du en ny kommandotolk, Bash eller terminalsession och anger följande kommando:
az webapp log tail --name webappname --resource-group myResourceGroup
Kommandot az webapp log tail har alternativ för att filtrera utdata med hjälp --provider
av alternativet .
Om du vill ladda ned loggfilerna som en enda ZIP-fil med hjälp av Azure CLI öppnar du en ny kommandotolk, Bash eller terminalsession och anger följande kommando:
az webapp log download --resource-group resourcegroupname --name functionappname
Du måste ha aktiverat filsystemloggning i Azure-portalen eller Azure CLI innan du kör det här kommandot.
Miljövariabler
I Functions exponeras appinställningar, till exempel tjänst niska veze, som miljövariabler under körningen. Du kan komma åt de här inställningarna med hjälp av , System.getenv("AzureWebJobsStorage")
.
I följande exempel hämtas programinställningen med nyckeln med namnet 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);
}
}
Använda beroendeinmatning i Java Functions
Azure Functions Java stöder designmönstret för beroendeinmatning (DI), vilket är en teknik för att uppnå inversion av kontroll (IoC) mellan klasser och deras beroenden. Java Azure Functions ger en krok för att integrera med populära ramverk för beroendeinmatning i dina Functions Apps. Azure Functions Java SPI innehåller ett gränssnitt för FunctionInstanceInjector. Genom att implementera det här gränssnittet kan du returnera en instans av funktionsklassen och dina funktioner anropas på den här instansen. Detta ger ramverk som Spring, Quarkus, Google Guice, Dagger osv. möjligheten att skapa funktionsinstansen och registrera den i sin IOK-container. Det innebär att du kan använda dessa ramverk för beroendeinmatning för att hantera dina funktioner på ett naturligt sätt.
Kommentar
Microsoft Azure Functions Java SPI Types (azure-function-java-spi) är ett paket som innehåller alla SPI-gränssnitt för tredje part att interagera med Microsoft Azure Functions-körning.
Injektor för funktionsinstans för beroendeinmatning
azure-function-java-spi innehåller ett gränssnitt för 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;
}
Fler exempel som använder FunctionInstanceInjector för att integrera med beroendeinmatningsramverk finns på den här lagringsplatsen.
Nästa steg
Mer information om Azure Functions Java-utveckling finns i följande resurser:
- Metodtips för Azure Functions
- Azure Functions, info för utvecklare
- Azure Functions-utlösare och bindningar
- Lokal utveckling och felsökning med Visual Studio Code, IntelliJ och Eclipse
- Fjärrfelsöka Java-funktioner med Hjälp av Visual Studio Code
- Maven-plugin-program för Azure Functions
- Effektivisera funktionsskapandet genom
azure-functions:add
målet och förbered en mellanlagringskatalog för ZIP-fildistribution.