Event Hubs gebruiken in Spring-toepassingen

In dit artikel leest u hoe u Azure Event Hubs gebruikt in Java toepassingen die zijn gebouwd met het Spring Framework.

Azure Event Hubs is een big data-streamingplatform en gebeurtenisopnameservice. Het kan miljoenen gebeurtenissen per seconde ontvangen en verwerken. Gegevens die naar een Event Hub worden verzonden, kunnen worden omgezet en opgeslagen door gebruik te maken van een provider voor realtime analytische gegevens of batchverwerking/opslagadapters.

Spring Cloud Azure biedt verschillende modules voor het verzenden van berichten naar en het ontvangen van berichten van Event Hubs met behulp van Spring-frameworks.

U kunt de volgende modules onafhankelijk gebruiken of combineren voor verschillende gebruiksvoorbeelden:

Vereisten

  • Een Azure Event Hubs exemplaar. Zie Quickstart: Een Event Hub maken met Azure portal voor meer informatie.

  • Een Azure Storage-account voor Event Hubs-controlepunten. Zie Een opslagaccount maken voor meer informatie.

  • Een Spring Boot-toepassing. Als u er nog geen hebt, maakt u een Maven-project met de Spring Initializr. Vergeet niet om Maven Project te selecteren en voeg onder Afhankelijkheden de afhankelijkheid Spring Web toe en selecteer vervolgens Java versie 8 of hoger.

Notitie

Als u uw account toegang wilt verlenen tot resources, wijst u in Azure Event Hubs de rol Azure Event Hubs Data Receiver en Azure Event Hubs Data Sender toe aan het Microsoft Entra account dat u momenteel gebruikt. Wijs vervolgens in het Azure Storage-account de rol Storage Blob Data Contributor toe aan het Microsoft Entra account dat u momenteel gebruikt. Voor meer informatie over het verlenen van toegangsrollen, zie Assign Azure roles using the Azure portal en Authorize access to Event Hubs resources using Microsoft Entra ID.

Belangrijk

Spring Boot versie 2.5 of hoger is vereist om de stappen in deze zelfstudie uit te voeren.

Uw lokale omgeving voorbereiden

In deze handleiding hebben de configuraties en code geen authenticatiebewerkingen. Voor het maken van verbinding met een Azure-service is echter verificatie vereist. Als u de verificatie wilt voltooien, moet u de Azure Identity-clientbibliotheek gebruiken. Spring Cloud Azure maakt gebruik van DefaultAzureCredential, die de Azure Identity-bibliotheek biedt om u te helpen referenties te verkrijgen zonder codewijzigingen.

DefaultAzureCredential ondersteunt meerdere verificatiemethoden en bepaalt welke methode tijdens runtime moet worden gebruikt. Met deze aanpak kan uw app verschillende verificatiemethoden gebruiken in verschillende omgevingen, zoals lokale of productieomgevingen, zonder omgevingsspecifieke code te implementeren. Zie de sectie DefaultAzureCredential van Authenticate Azure-hosted Java applications voor meer informatie.

Zie Azure-verificatie in Java ontwikkelomgevingen als u Azure CLI, IntelliJ of andere methoden wilt gebruiken om de verificatie in lokale ontwikkelomgevingen te voltooien. Als u de verificatie in Azure hostingomgevingen wilt voltooien, raden we u aan beheerde identiteit te gebruiken. Zie Wat zijn beheerde identiteiten voor Azure resources?

Spring Cloud Azure Event Hubs Starter gebruiken

De module Spring Cloud Azure Event Hubs Starter importeert de Event Hubs Java-clientbibliotheek met het Spring Boot-framework. U kunt Spring Cloud Azure en de Azure SDK samen gebruiken in een niet-wederzijds exclusief patroon. U kunt dus de Event Hubs Java-client-API blijven gebruiken in uw Spring-toepassing.

Afhankelijkheden toevoegen

Als u de Spring Cloud Azure Event Hubs Starter-module wilt installeren, voegt u de volgende afhankelijkheden toe aan het bestand pom.xml:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Het Spring Cloud-Azure Event Hubs-artefact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-eventhubs</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

In deze handleiding leert u hoe u de Event Hubs-Java-clients gebruikt in de context van een Spring-toepassing. Hier introduceren we de volgende twee opties:

  • Gebruik automatische configuratie van Spring Boot en gebruik out-of-the-box-clients vanuit de Spring-context (aanbevolen).
  • Bouw de client programmatisch.

De werkwijze van het automatisch verbinden van client beans vanuit de Spring IoC-container heeft de volgende voordelen, die u een flexibelere en efficiëntere ervaring kunnen bieden bij het ontwikkelen met Event Hubs-clients.

  • Hiermee wordt de externe configuratie toegepast, zodat u met dezelfde toepassingscode in verschillende omgevingen kunt werken.
  • U kunt het proces voor het leren van het opbouwpatroon delegeren aan het Spring Boot-framework en deze client registreren bij de toepassingscontext. Met deze delegatie kunt u zich richten op hoe u de clients kunt gebruiken volgens uw eigen bedrijfsbehoeften.
  • U kunt de statusindicator op een eenvoudige manier gebruiken om de status en status van uw toepassing en interne onderdelen te controleren.

De volgende secties bevatten codevoorbeelden die u laten zien hoe u deze kunt gebruiken EventProcessorClient en EventHubProducerClient met de twee alternatieven.

Notitie

Azure Java SDK voor Event Hubs biedt meerdere clients om te communiceren met Event Hubs. De starter biedt ook automatische configuratie voor alle Event Hubs-clients en clientbouwers. In dit artikel worden alleen EventProcessorClient en EventHubProducerClient als voorbeelden gebruikt.

Spring Boot AutoConfiguration gebruiken

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstellingen om uw Event Hubs-naamruimte en Event Hub-naam te configureren:

    spring.cloud.azure.eventhubs.namespace=<your event-hubs-namespace>
    spring.cloud.azure.eventhubs.event-hub-name=<your-event-hub-name>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name=<your-storage-account-name>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name=<your-storage-account-container-name>
    spring.cloud.azure.eventhubs.processor.consumer-group=$Default
    
  2. Maak een nieuwe EventHubProcessorClientConfiguration Java-klasse, zoals wordt weergegeven in het volgende voorbeeld. Deze klasse wordt gebruikt om het bericht en de fouthandler voor EventProcessorClientte registreren.

    import com.azure.spring.cloud.service.eventhubs.consumer.EventHubsErrorHandler;
    import com.azure.spring.cloud.service.eventhubs.consumer.EventHubsRecordMessageListener;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class EventHubProcessorClientConfiguration {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubProcessorClientConfiguration.class);
    
        @Bean
        EventHubsRecordMessageListener processEvent() {
            return eventContext->LOGGER.info("Processing event from partition {} with sequence number {} with body: {}",
                eventContext.getPartitionContext().getPartitionId(), eventContext.getEventData().getSequenceNumber(),
                eventContext.getEventData().getBodyAsString());
        }
    
        @Bean
        EventHubsErrorHandler processError() {
            return errorContext->LOGGER.info("Error occurred in partition processor for partition {}, {}",
                errorContext.getPartitionContext().getPartitionId(),
                errorContext.getThrowable());
        }
    
    }
    
  3. Injecteer de EventProcessorClient en EventHubProducerClient in uw Spring-toepassing en roep de gerelateerde API's aan om berichten te verzenden en te ontvangen, zoals wordt weergegeven in het volgende voorbeeld:

    import com.azure.messaging.eventhubs.EventData;
    import com.azure.messaging.eventhubs.EventHubProducerClient;
    import com.azure.messaging.eventhubs.EventProcessorClient;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import java.util.Collections;
    import java.util.concurrent.TimeUnit;
    
    @SpringBootApplication
    public class EventHubClientApplication implements CommandLineRunner {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubClientApplication.class);
        private final EventHubProducerClient eventHubProducerClient;
        private final EventProcessorClient eventProcessorClient;
    
        public EventHubClientApplication(EventHubProducerClient eventHubProducerClient,
                                         EventProcessorClient eventProcessorClient) {
            this.eventHubProducerClient = eventHubProducerClient;
            this.eventProcessorClient = eventProcessorClient;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EventHubClientApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            eventProcessorClient.start();
            // Wait for the processor client to be ready
            TimeUnit.SECONDS.sleep(10);
    
            eventHubProducerClient.send(Collections.singletonList(new EventData("Hello World")));
            LOGGER.info("Successfully sent a message to Event Hubs.");
            eventHubProducerClient.close();
            LOGGER.info("Skip stopping and closing the processor since the processor may not complete the receiving process yet.");
        }
    
    }
    
  4. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Successfully sent a message to Event Hubs.
    ...
    Processing event from partition 0 with sequence number 0 with body: Hello World
    ...
    Stopping and closing the processor.
    

De client programmatisch bouwen

U kunt zelf de clientcomponenten bouwen, maar het proces is ingewikkeld. In Spring Boot-toepassingen moet u eigenschappen beheren, het opbouwpatroon leren en de client registreren bij de context van uw Spring-toepassing. In de volgende stappen ziet u hoe u dit doet:

  1. Maak een nieuwe EventHubClientConfiguration Java-klasse, zoals wordt weergegeven in het volgende voorbeeld. Deze klasse wordt gebruikt om de EventProcessorClient en EventHubProducerClient bonen te declareren. Zorg ervoor dat u de tijdelijke aanduidingen <your event-hubs-namespace>, <your-event-hub-name>, <your-storage-account-name> en <your-storage-account-container-name> vervangt door uw werkelijke waarden.

    import com.azure.identity.DefaultAzureCredentialBuilder;
    import com.azure.messaging.eventhubs.EventHubClientBuilder;
    import com.azure.messaging.eventhubs.EventHubProducerClient;
    import com.azure.messaging.eventhubs.EventProcessorClient;
    import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
    import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
    import com.azure.messaging.eventhubs.models.ErrorContext;
    import com.azure.messaging.eventhubs.models.EventContext;
    import com.azure.storage.blob.BlobContainerAsyncClient;
    import com.azure.storage.blob.BlobContainerClientBuilder;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class EventHubClientConfiguration {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubClientConfiguration.class);
        private static final String EVENT_HUB_FULLY_QUALIFIED_NAMESPACE = "<your event-hubs-namespace>.servicebus.windows.net";
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
        private static final String CONSUMER_GROUP = "$Default";
        private static final String STORAGE_ACCOUNT_ENDPOINT = "https://<your-storage-account-name>.blob.core.windows.net";
        private static final String STORAGE_CONTAINER_NAME = "<your-storage-account-container-name>";
    
        @Bean
        EventHubClientBuilder eventHubClientBuilder() {
            return new EventHubClientBuilder().credential(EVENT_HUB_FULLY_QUALIFIED_NAMESPACE, EVENT_HUB_NAME,
                new DefaultAzureCredentialBuilder()
                    .build());
        }
    
        @Bean
        BlobContainerClientBuilder blobContainerClientBuilder() {
            return new BlobContainerClientBuilder().credential(new DefaultAzureCredentialBuilder()
                                                       .build())
                                                   .endpoint(STORAGE_ACCOUNT_ENDPOINT)
                                                   .containerName(STORAGE_CONTAINER_NAME);
        }
    
        @Bean
        BlobContainerAsyncClient blobContainerAsyncClient(BlobContainerClientBuilder blobContainerClientBuilder) {
            return blobContainerClientBuilder.buildAsyncClient();
        }
    
        @Bean
        EventProcessorClientBuilder eventProcessorClientBuilder(BlobContainerAsyncClient blobContainerAsyncClient) {
            return new EventProcessorClientBuilder().credential(EVENT_HUB_FULLY_QUALIFIED_NAMESPACE, EVENT_HUB_NAME,
                                                        new DefaultAzureCredentialBuilder()
                                                            .build())
                                                    .consumerGroup(CONSUMER_GROUP)
                                                    .checkpointStore(new BlobCheckpointStore(blobContainerAsyncClient))
                                                    .processEvent(EventHubClientConfiguration::processEvent)
                                                    .processError(EventHubClientConfiguration::processError);
        }
    
        @Bean
        EventHubProducerClient eventHubProducerClient(EventHubClientBuilder eventHubClientBuilder) {
            return eventHubClientBuilder.buildProducerClient();
    
        }
    
        @Bean
        EventProcessorClient eventProcessorClient(EventProcessorClientBuilder eventProcessorClientBuilder) {
            return eventProcessorClientBuilder.buildEventProcessorClient();
        }
    
        public static void processEvent(EventContext eventContext) {
            LOGGER.info("Processing event from partition {} with sequence number {} with body: {}",
                eventContext.getPartitionContext().getPartitionId(), eventContext.getEventData().getSequenceNumber(),
                eventContext.getEventData().getBodyAsString());
        }
    
        public static void processError(ErrorContext errorContext) {
            LOGGER.info("Error occurred in partition processor for partition {}, {}",
                errorContext.getPartitionContext().getPartitionId(),
                errorContext.getThrowable());
        }
    
    }
    
  2. Injecteer de EventProcessorClient en EventHubProducerClient in uw Spring-toepassing, zoals wordt weergegeven in het volgende voorbeeld:

    import com.azure.messaging.eventhubs.EventData;
    import com.azure.messaging.eventhubs.EventHubProducerClient;
    import com.azure.messaging.eventhubs.EventProcessorClient;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import java.util.Collections;
    import java.util.concurrent.TimeUnit;
    
    @SpringBootApplication
    public class EventHubClientApplication implements CommandLineRunner {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubClientApplication.class);
        private final EventHubProducerClient eventHubProducerClient;
        private final EventProcessorClient eventProcessorClient;
    
        public EventHubClientApplication(EventHubProducerClient eventHubProducerClient,
                                         EventProcessorClient eventProcessorClient) {
            this.eventHubProducerClient = eventHubProducerClient;
            this.eventProcessorClient = eventProcessorClient;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EventHubClientApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            eventProcessorClient.start();
            // Wait for the processor client to be ready
            TimeUnit.SECONDS.sleep(10);
    
            eventHubProducerClient.send(Collections.singletonList(new EventData("Hello World")));
            LOGGER.info("Successfully sent a message to Event Hubs.");
            eventHubProducerClient.close();
            LOGGER.info("Stopping and closing the processor");
            eventProcessorClient.stop();
        }
    
    }
    
  3. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Successfully sent a message to Event Hubs.
    ...
    Processing event from partition 0 with sequence number 0 with body: Hello World
    ...
    Stopping and closing the processor.
    

In de volgende lijst ziet u enkele redenen waarom deze code niet flexibel of probleemloos is:

  • De Event Hubs-naamruimte en event hub-naam zijn vastgelegd in code.
  • Wanneer u @Value gebruikt om configuraties uit de Spring-omgeving te verkrijgen, kunt u geen IDE-hints hebben in het application.properties-bestand.
  • Als u een microservicescenario hebt, moet u de code in elk project dupliceren en het is eenvoudig om fouten te maken en moeilijk consistent te zijn.

Gelukkig hoef je zelf geen clientbeans te bouwen met Spring Cloud Azure. In plaats daarvan kunt u ze rechtstreeks injecteren en de configuratie-eigenschappen gebruiken waarmee u al bekend bent om de opslagwachtrij te configureren. Zie Spring Cloud Azure configuration voor meer informatie.

Spring Cloud Azure biedt ook de volgende globale configuraties voor verschillende scenario's. Zie de Global-configuratie voor Azure service-SDK's van de Spring Cloud Azure-configuratie voor meer informatie.

  • Proxy-opties.
  • Opties voor opnieuw proberen.
  • AMQP-transportclient-opties.

U kunt ook verbinding maken met verschillende Azure clouds. Zie Connect to different Azure clouds voor meer informatie.

Spring Messaging-Azure Event Hubs gebruiken

De module Spring Messaging Azure Event Hubs biedt ondersteuning voor Spring Messaging framework met Event Hubs.

Als u Spring Messaging Azure Event Hubs gebruikt, kunt u de volgende functies gebruiken:

  • EventHubsTemplate: Berichten asynchroon en synchroon verzenden naar een Event Hubs.
  • @EventHubsListener: Markeer een methode om als doel te dienen van een Event Hubs-berichtenluisteraar op de bestemming.

Deze handleiding laat zien hoe u Spring Messaging Azure Event Hubs gebruikt om berichten te verzenden naar en te ontvangen van Event Hubs.

Afhankelijkheden toevoegen

Als u de Spring Messaging Azure Event Hubs-module wilt installeren, voegt u de volgende afhankelijkheden toe aan uw bestand pom.xml:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Spring Cloud Azure starter, Spring Messaging Event Hubs, en Azure Event Hubs Checkpoint Store-artefacten:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-messaging-azure-eventhubs</artifactId>
    </dependency>
    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstellingen om de Event Hubs-naamruimte en storage-blob te configureren:

    spring.cloud.azure.eventhubs.namespace=<your event-hubs-namespace>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name=<your-storage-account-name>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name=<your-storage-account-container-name>
    
  2. Maak een nieuwe ConsumerService Java-klasse, zoals wordt weergegeven in het volgende voorbeeld. Deze klasse wordt gebruikt om een ontvanger van een bericht te definiëren. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

    import com.azure.spring.messaging.eventhubs.implementation.core.annotation.EventHubsListener;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ConsumerService {
    
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
        private static final String CONSUMER_GROUP = "$DEFAULT";
    
        @EventHubsListener(destination = EVENT_HUB_NAME, group = CONSUMER_GROUP)
        public void handleMessageFromEventHub(String message) {
            System.out.printf("New message received: %s%n", message);
        }
    
    }
    
  3. Verbind een afzender en een ontvanger om berichten te verzenden en te ontvangen met Spring, zoals wordt weergegeven in het volgende voorbeeld. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

    import com.azure.spring.messaging.eventhubs.core.EventHubsTemplate;
    import com.azure.spring.messaging.implementation.annotation.EnableAzureMessaging;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.messaging.support.MessageBuilder;
    
    @SpringBootApplication
    @EnableAzureMessaging
    public class EventHubMessagingApplication {
    
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubMessagingApplication.class);
    
        public static void main(String[] args) {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(EventHubMessagingApplication.class);
            EventHubsTemplate eventHubsTemplate = applicationContext.getBean(EventHubsTemplate.class);
            LOGGER.info("Sending a message to the Event Hubs.");
            eventHubsTemplate.sendAsync(EVENT_HUB_NAME, MessageBuilder.withPayload("Hello world").build()).subscribe();
        }
    
    }
    

    Aanbeveling

    Vergeet niet om de @EnableAzureMessaging annotatie toe te voegen, waarmee de detectie van methoden die met @EventHubsListener zijn geannoteerd, wordt geactiveerd, wat resulteert in het aanmaken van de container voor de berichtlistener op de achtergrond.

  4. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Sending a message to the Event Hubs.
    New message received: Hello world
    

Gebruik Spring Integration met Azure Event Hubs

De module Spring Integration Azure Event Hubs biedt ondersteuning voor het framework Spring Integration met Event Hubs.

Als uw Spring-toepassing gebruikmaakt van Spring Integration-berichtkanalen, kunt u berichten routeren tussen uw berichtkanalen en Event Hubs met behulp van kanaaladapters.

Een binnenkomende kanaaladapter stuurt berichten van een Event Hub door naar een berichtkanaal. Een uitgaande kanaaladapter publiceert berichten van een berichtkanaal naar een Event Hub.

Deze handleiding laat zien hoe u Spring Integration Azure Event Hubs gebruikt om berichten te verzenden naar en te ontvangen van Event Hubs.

Afhankelijkheden toevoegen

Als u de Spring Cloud Azure Event Hubs Integration Starter-module wilt installeren, voegt u de volgende afhankelijkheden toe aan uw bestand pom.xml:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Het Spring Cloud Azure Event Hubs-integratieartefact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-integration-eventhubs</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstellingen om de Event Hubs-naamruimte en storage-blob te configureren:

    spring.cloud.azure.eventhubs.namespace=<your event-hubs-namespace>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name=<your-storage-account-name>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name=<your-storage-account-container-name>
    
  2. Maak een nieuwe MessageReceiveConfiguration Java-klasse, zoals wordt weergegeven in het volgende voorbeeld. Deze klasse wordt gebruikt om een ontvanger van een bericht te definiëren. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

    import com.azure.spring.integration.eventhubs.inbound.EventHubsInboundChannelAdapter;
    import com.azure.spring.messaging.eventhubs.core.EventHubsProcessorFactory;
    import com.azure.spring.messaging.eventhubs.core.checkpoint.CheckpointConfig;
    import com.azure.spring.messaging.eventhubs.core.checkpoint.CheckpointMode;
    import com.azure.spring.messaging.eventhubs.core.listener.EventHubsMessageListenerContainer;
    import com.azure.spring.messaging.eventhubs.core.properties.EventHubsContainerProperties;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.integration.annotation.ServiceActivator;
    import org.springframework.integration.channel.DirectChannel;
    import org.springframework.messaging.MessageChannel;
    
    @Configuration
    public class MessageReceiveConfiguration {
    
        private static final String INPUT_CHANNEL = "input";
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
        private static final String CONSUMER_GROUP = "$Default";
        private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiveConfiguration.class);
    
        @ServiceActivator(inputChannel = INPUT_CHANNEL)
        public void messageReceiver(byte[] payload) {
            String message = new String(payload);
            LOGGER.info("New message received: {}", message);
        }
    
        @Bean
        public EventHubsMessageListenerContainer messageListenerContainer(EventHubsProcessorFactory processorFactory) {
            EventHubsContainerProperties containerProperties = new EventHubsContainerProperties();
            containerProperties.setEventHubName(EVENT_HUB_NAME);
            containerProperties.setConsumerGroup(CONSUMER_GROUP);
            containerProperties.setCheckpointConfig(new CheckpointConfig(CheckpointMode.MANUAL));
            return new EventHubsMessageListenerContainer(processorFactory, containerProperties);
        }
    
        @Bean
        public EventHubsInboundChannelAdapter messageChannelAdapter(@Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
                                                                    EventHubsMessageListenerContainer listenerContainer) {
            EventHubsInboundChannelAdapter adapter = new EventHubsInboundChannelAdapter(listenerContainer);
            adapter.setOutputChannel(inputChannel);
            return adapter;
        }
    
        @Bean
        public MessageChannel input() {
            return new DirectChannel();
        }
    
    }
    
  3. Maak een nieuwe MessageSendConfiguration Java-klasse, zoals wordt weergegeven in het volgende voorbeeld. Deze klasse wordt gebruikt om een afzender van een bericht te definiëren. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

    import com.azure.spring.integration.core.handler.DefaultMessageHandler;
    import com.azure.spring.messaging.eventhubs.core.EventHubsTemplate;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.integration.annotation.MessagingGateway;
    import org.springframework.integration.annotation.ServiceActivator;
    import org.springframework.messaging.MessageHandler;
    import org.springframework.util.concurrent.ListenableFutureCallback;
    
    @Configuration
    public class MessageSendConfiguration {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(MessageSendConfiguration.class);
        private static final String OUTPUT_CHANNEL = "output";
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
    
        @Bean
        @ServiceActivator(inputChannel = OUTPUT_CHANNEL)
        public MessageHandler messageSender(EventHubsTemplate eventHubsTemplate) {
            DefaultMessageHandler handler = new DefaultMessageHandler(EVENT_HUB_NAME, eventHubsTemplate);
            handler.setSendCallback(new ListenableFutureCallback<Void>() {
                @Override
                public void onSuccess(Void result) {
                    LOGGER.info("Message was sent successfully.");
                }
    
                @Override
                public void onFailure(Throwable ex) {
                    LOGGER.error("There was an error sending the message.", ex);
                }
            });
    
            return handler;
        }
    
        @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL)
        public interface EventHubOutboundGateway {
            void send(String text);
        }
    
    }
    
  4. Verbind een afzender en een ontvanger om berichten te verzenden en te ontvangen met Spring, zoals wordt weergegeven in het volgende voorbeeld:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.integration.config.EnableIntegration;
    
    @SpringBootApplication
    @EnableIntegration
    @Configuration(proxyBeanMethods = false)
    public class EventHubIntegrationApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(EventHubIntegrationApplication.class, args);
            MessageSendConfiguration.EventHubOutboundGateway outboundGateway = applicationContext.getBean(MessageSendConfiguration.EventHubOutboundGateway.class);
            outboundGateway.send("Hello World");
        }
    }
    

    Aanbeveling

    Vergeet niet om de @EnableIntegration aantekening toe te voegen, waardoor de Spring Integration-infrastructuur mogelijk is.

  5. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Message was sent successfully.
    New message received: Hello World
    

Spring Cloud Azure Stream Event Hubs Binder gebruiken

Gebruik de Spring Azure Event Hubs Cloud Binder-module om de Event Hubs-API aan te roepen in een Spring Cloud Stream-toepassing.

Deze handleiding laat zien hoe u Spring Cloud Stream Event Hubs Binder gebruikt om berichten te verzenden naar en te ontvangen van Event Hubs.

Afhankelijkheden toevoegen

Als u de Spring Cloud Azure Event Hubs Stream Binder-module wilt installeren, voegt u de volgende afhankelijkheden toe aan uw bestand pom.xml:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Het Spring Cloud Azure Event Hubs Stream Binder-artefact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-stream-binder-eventhubs</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstellingen om de Event Hubs-naamruimte en storage-blob te configureren:

    spring.cloud.azure.eventhubs.namespace=<your event-hubs-namespace>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name=<your-storage-account-name>
    spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name=<your-storage-account-container-name>
    
  2. Maak de ontvanger van het bericht.

    Om uw toepassing als gebeurtenishandler te gebruiken, configureert u de invoerbinding door het uitvoeren van de volgende taken:

    • Declareer een Consumer bean die berichtafhandelingslogica definieert. De volgende Consumer bean heeft bijvoorbeeld de naam consume:

      @Bean
      public Consumer<Message<String>> consume() {
           return message -> {
               System.out.printf("New message received: %s%n", message.getPayload());
           };
      }
      
    • Voeg de volgende configuratie toe om de Event Hub naam voor verbruik op te geven. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

      # name for the above `Consumer` bean
      spring.cloud.stream.function.definition=consume
      spring.cloud.stream.bindings.consume-in-0.destination=<your-event-hub-name>
      spring.cloud.stream.bindings.consume-in-0.group=$Default
      spring.cloud.stream.eventhubs.bindings.consume-in-0.consumer.checkpoint.mode=MANUAL
      
  3. Maak de afzender van het bericht.

    Als u uw toepassing wilt gebruiken als gebeurtenisbron, configureert u de uitvoerbindinger door de volgende taken uit te voeren:

    • Definieer een Supplier bean die definieert waar berichten vandaan komen in uw toepassing, zoals wordt weergegeven in het volgende voorbeeld:

      @Bean
      public Supplier<Message<String>> supply() {
          return () -> {
              System.out.println("Sending a message.");
              return MessageBuilder.withPayload("Hello world").build();
          };
      }
      
    • Voeg de volgende configuratie toe om de Event Hub naam voor het verzenden op te geven. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

      # "consume" is added from the above step
      spring.cloud.stream.function.definition=consume;supply
      spring.cloud.stream.bindings.supply-out-0.destination=<your-event-hub-name>
      
  4. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Sending a message.
    New message received: Hello world.
    

Spring Kafka gebruiken met Azure Event Hubs

Event Hubs biedt een Kafka-eindpunt dat uw bestaande Kafka-toepassingen kunnen gebruiken. Deze benadering biedt een alternatief voor het uitvoeren van uw eigen Kafka-cluster. Event Hubs werkt met veel van uw bestaande Kafka-toepassingen. Zie Event Hubs voor Apache Kafka voor meer informatie.

Deze handleiding laat zien hoe u Azure Event Hubs en Spring Kafka gebruikt om berichten te verzenden naar en te ontvangen van Event Hubs.

Afhankelijkheden toevoegen

Als u de Spring Cloud Azure starter- en Spring Kafka-modules wilt installeren, voegt u de volgende afhankelijkheden toe aan uw pom.xml-bestand:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Het Spring Cloud Azure starter en het Spring Kafka-artefact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstelling om de Event Hubs-naamruimte te configureren:

    spring.kafka.bootstrap-servers=<your event-hubs-namespace>.servicebus.windows.net:9093
    
  2. Gebruik KafkaTemplate dit om berichten te verzenden en @KafkaListener berichten te ontvangen, zoals wordt weergegeven in het volgende voorbeeld. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.kafka.annotation.KafkaListener;
    import org.springframework.kafka.core.KafkaTemplate;
    
    @SpringBootApplication
    public class EventHubKafkaApplication implements CommandLineRunner {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(EventHubKafkaApplication.class);
        private static final String EVENT_HUB_NAME = "<your-event-hub-name>";
        private static final String CONSUMER_GROUP = "$Default";
        private final KafkaTemplate<String, String> kafkaTemplate;
    
        public EventHubKafkaApplication(KafkaTemplate<String, String> kafkaTemplate) {
            this.kafkaTemplate = kafkaTemplate;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EventHubKafkaApplication.class, args);
        }
    
        @Override
        public void run(String... args) {
            kafkaTemplate.send(EVENT_HUB_NAME, "Hello World");
            LOGGER.info("Message was sent successfully.");
        }
    
        @KafkaListener(topics = EVENT_HUB_NAME, groupId = CONSUMER_GROUP)
        public void receive(String message) {
            LOGGER.info("New message received: {}", message);
        }
    
    }
    
  3. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Message was sent successfully.
    New message received: Hello world
    

Spring Cloud Stream Kafka Binder gebruiken met Azure Event Hubs

Spring Cloud Stream is een framework waarmee toepassingsontwikkelaars berichtgestuurde microservices kunnen schrijven. De brug tussen een berichtensysteem en Spring Cloud Stream is via de binderabstractie. Binders bestaan voor verschillende berichtensystemen, maar een van de meest gebruikte binders is voor Apache Kafka.

Deze handleiding laat zien hoe u Azure Event Hubs en Spring Cloud Stream Kafka Binder kunt gebruiken om berichten te verzenden naar en te ontvangen van Event Hubs.

Afhankelijkheden toevoegen

Als u de Spring Cloud Azure starter- en Spring Cloud Stream-binder Kafka-modules wilt installeren, voegt u de volgende afhankelijkheden toe aan uw bestand pom.xml:

  • Het Spring Cloud Azure Materiaaloverzicht (BOM):

    <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-dependencies</artifactId>
           <version>7.4.0</version>
           <type>pom</type>
           <scope>import</scope>
           </dependency>
       </dependencies>
    </dependencyManagement>
    

    Notitie

    Als u Spring Boot 4.0.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 7.4.0.

    Als u Spring Boot 3.5.x gebruikt, stelt u de spring-cloud-azure-dependencies versie in op 6.5.0.

    Als u Spring Boot 3.1.x-3.5.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 5.25.0.

    Als u Spring Boot 2.x gebruikt, moet u de spring-cloud-azure-dependencies versie instellen op 4.20.0.

    Deze BOM (Bill of Material) moet worden geconfigureerd in de <dependencyManagement> sectie van uw pom.xml-bestand. Dit zorgt ervoor dat alle Spring Cloud-Azure afhankelijkheden dezelfde versie gebruiken.

    Zie Which Version of Spring Cloud Azure Should I Use voor meer informatie over de versie die voor deze BOM wordt gebruikt.

  • Het Spring Cloud Azure startartefact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-stream-binder-kafka</artifactId>
    </dependency>
    

Codeer de toepassing om berichten te verzenden en te ontvangen

Als u berichten wilt verzenden naar en ontvangen van Event Hubs, configureert u de toepassing met behulp van de volgende stappen:

  1. Gebruik de volgende eigenschapsinstelling om de Kafka-broker te configureren:

    spring.cloud.stream.kafka.binder.brokers=<your event-hubs-namespace>.servicebus.windows.net:9093
    
  2. Maak de ontvanger van het bericht.

    Om uw toepassing als gebeurtenishandler te gebruiken, configureert u de invoerbinding door het uitvoeren van de volgende taken:

    • Declareer een Consumer bean die berichtafhandelingslogica definieert. De volgende Consumer bean heeft bijvoorbeeld de naam consume:

      @Bean
      public Consumer<Message<String>> consume() {
          return message -> {
              System.out.printf("New message received: %s%n", message.getPayload());
          };
      }
      
    • Voeg de volgende configuratie toe om de Event Hub naam voor verbruik op te geven. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

      # name for the above `Consumer` bean
      spring.cloud.stream.function.definition=consume
      spring.cloud.stream.bindings.consume-in-0.destination=<your-event-hub-name>
      spring.cloud.stream.bindings.consume-in-0.group=$Default
      
  3. Maak de afzender van het bericht.

    Als u uw toepassing wilt gebruiken als gebeurtenisbron, configureert u de uitvoerbindinger door de volgende taken uit te voeren:

    • Definieer een Supplier bean die definieert waar berichten vandaan komen in uw toepassing, zoals wordt weergegeven in het volgende voorbeeld:

      @Bean
      public Supplier<Message<String>> supply() {
          return () -> {
              System.out.println("Sending a message.");
              return MessageBuilder.withPayload("Hello world").build();
          };
      }
      
    • Voeg de volgende configuratie toe om de Event Hub naam voor het verzenden op te geven. Vervang de <your-event-hub-name> tijdelijke aanduiding door de werkelijke waarde.

      # "consume" is added from the above step
      spring.cloud.stream.function.definition=consume;supply
      spring.cloud.stream.bindings.supply-out-0.destination=<your-event-hub-name>
      
  4. Start de toepassing. U ziet logboeken die vergelijkbaar zijn met het volgende voorbeeld:

    Sending a message.
    New message received: Hello world.
    

Implementeren in Azure Spring Apps

Nu de Spring Boot-toepassing lokaal wordt uitgevoerd, is het tijd om deze naar productie te verplaatsen. Azure Spring Apps maakt het eenvoudig om Spring Boot-toepassingen te implementeren in Azure zonder codewijzigingen. De service beheert de infrastructuur van Spring-toepassingen, zodat ontwikkelaars zich kunnen richten op hun code. Azure Spring Apps biedt levenscyclusbeheer met behulp van uitgebreide bewaking en diagnose, configuratiebeheer, servicedetectie, CI/CD-integratie, blauwgroene implementaties en meer. Zie Uw eerste toepassing implementeren voor Azure Spring Apps om uw toepassing te implementeren in Azure Spring Apps.

Volgende stappen

Zie ook

Zie Wat is Spring Cloud Azure? voor meer informatie over de andere Spring Boot Starters die beschikbaar zijn voor Microsoft Azure>