Executando Múltiplas Implementações de Interface em Sequência no Java

Interface Definidora

Pirmeiro, definimos uma interface que servirá como contrato para as implementações. Esta interface possui um método chave que determina o fluxo de execução.


package com.example.interfaces;

public interface ProcessadorDeComandos {
   /**
    * Retorna -1 para interromper a execução sequencial.
    * Retorna 0 para continuar para a próxima implementação.
    *
    * @return O status da execução.
    */
   Integer executar();
}
   

Implementações da Interface

A seguir, criamos as classes concretas que implementam a interface ProcessadorDeComandos. Para controlar a ordem de execução, utilizamos a anotação @Order do Spring. Valores menores indicam maior prioridade (execução mais cedo).

Implementação Alpha


package com.example.processors;

import com.example.interfaces.ProcessadorDeComandos;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(2) // Ordem de execução 2
public class ImplementacaoAlpha implements ProcessadorDeComandos {
   @Override
   public Integer executar() {
       System.out.println("Executando Alpha...");
       return 0; // Continua a execução
   }
}
   

Implementação Beta


package com.example.processors;

import com.example.interfaces.ProcessadorDeComandos;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1) // Ordem de execução 1
public class ImplementacaoBeta implements ProcessadorDeComandos {
   @Override
   public Integer executar() {
       System.out.println("Executando Beta...");
       return 0; // Continua a execução
   }
}
   

Gerenciador de Execução

Esta classe é responsável por localizar todas as implementações da interface ProcessadorDeComandos registradas no contêiner Spring e executá-las em uma ordem definida pela anotação @Order. A execução é interrompida se algum processador retornar -1.


package com.example.core;

import com.example.interfaces.ProcessadorDeComandos;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Comparator;
import java.util.Map;

@Component
public class GerenciadorDeProcessadores {

   private final ApplicationContext context;

   @Autowired
   public GerenciadorDeProcessadores(ApplicationContext context) {
       this.context = context;
   }

   public void iniciarProcessamento() {
       // Obtém todos os beans que implementam ProcessadorDeComandos
       Map<string processadordecomandos=""> processadoresMap = context.getBeansOfType(ProcessadorDeComandos.class);

       // Converte para uma coleção e ordena pela anotação @Order
       Collection<processadordecomandos> processadores = processadoresMap.values();
       processadores.stream()
               .sorted(Comparator.comparingInt(processor -> {
                   // Extrai o valor da anotação @Order
                   Integer orderValue = AnnotationUtils.findAnnotation(processor.getClass(), Order.class).value();
                   return orderValue != null ? orderValue : Integer.MAX_VALUE; // Valor padrão se @Order não estiver presente
               }))
               .forEach(processor -> {
                   System.out.println("Instância: " + processor.getClass().getSimpleName());
                   Integer status = processor.executar();
                   System.out.println("Status da execução: " + status);
                   // Interrompe se o status for -1
                   if (status != null && status == -1) {
                       System.out.println("Execução interrompida pelo processador.");
                       return; // Para a iteração do stream
                   }
               });
   }
}
   </processadordecomandos></string>

Ponto de Entrada de Teste

Um exemplo de como acionar o gerenciador de processamento, por exemplo, a partir de um endpoint de controller.


package com.example.controller;

import com.example.core.GerenciadorDeProcessadores;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/commands")
public class ProcessadorController {

   private final GerenciadorDeProcessadores gerenciador;

   @Autowired
   public ProcessadorController(GerenciadorDeProcessadores gerenciador) {
       this.gerenciador = gerenciador;
   }

   @GetMapping("/run")
   public ResponseEntity<String> executarProcessadores() {
       gerenciador.iniciarProcessamento();
       return ResponseEntity.ok("Processamento iniciado.");
   }
}
   

Tags: java Spring Interface implementação ordem de execução

Publicado em 7-25 08:22