ASPECT-ORIENTED PROGRAMMING (AOP) APPLIED TO THE GENERATION OF CODE EXECUTION REPORTS IN JAVA
REGISTRO DOI: 10.69849/revistaft/ra10202511091056
Otávio Figueiredo1
Felipe Diniz Dallilo2
RESUMO
Este trabalho apresenta o desenvolvimento de um sistema capaz de monitorar e registrar o desempenho de métodos em aplicações Java, com base nos princípios da Programação Orientada a Aspectos (POA). A aplicação intercepta automaticamente métodos anotados e gera relatórios de execução contendo informações como tempo de processamento, consumo de memória e ocorrência de exceções.
Foram analisados dois tipos de operações: algoritmos de ordenação (Bubble Sort e Quick Sort), representando tarefas de processamento em memória, e operações em banco de dados MongoDB, representando atividades de persistência. As métricas coletadas são registradas em um arquivo CSV, que pode ser aberto e analisado no Microsoft Excel, possibilitando comparações detalhadas de desempenho entre diferentes tipos de processamento.
Os resultados demonstram que o uso de POA permite a geração automatizada e não intrusiva de relatórios de execução, fornecendo uma visão precisa do comportamento da aplicação e facilitando a análise de eficiência e consumo de recursos em ambientes reais de desenvolvimento.
Palavras-chave: Programação Orientada a Aspectos; Java; Relatório de Execução; Algoritmos de Ordenação; Operações em Banco de Dados.
Abstract: This study presents the development of a system capable of monitoring and recording the performance of methods in Java applications, based on the principles of AspectOriented Programming (AOP). The application automatically intercepts annotated methods and generates execution reports containing information such as processing time, memory usage, and exception occurrences.
Two types of operations were analyzed: sorting algorithms (Bubble Sort and Quick Sort), representing in-memory processing tasks, and MongoDB database operations, representing data persistence activities. The collected metrics are stored in a CSV file, which can be opened and analyzed in Microsoft Excel, enabling detailed performance comparisons between different processing types.
The results demonstrate that the use of AOP allows for the automated and non-intrusive generation of execution reports, providing an accurate view of application behavior and facilitating the analysis of efficiency and resource consumption in real development environments.
Keywords: Aspect-Oriented Programming; Java; Execution Report; Sorting Algorithms; Database Operations.
1 INTRODUÇÃO
A busca por otimização e monitoramento de desempenho em aplicações Java tem sido um dos desafios enfrentados por desenvolvedores e arquitetos de software. Muitas vezes, medir o tempo de execução de métodos e entender o fluxo de chamadas dentro de um sistema requer a inserção manual de código para logging e monitoramento, o que pode tornar o código mais complexo e difícil de manter. Neste contexto, a Programação Orientada a Aspectos (POA) surge como uma abordagem poderosa para desacoplar funcionalidades transversais, como geração de relatórios de execução de código, da lógica central da aplicação.
O Spring Framework, amplamente utilizado no desenvolvimento de aplicações Java, fornece suporte nativo à POA, permitindo interceptar chamadas de métodos e registrar dados importantes sem modificar diretamente o código-fonte dos métodos monitorados. Dessa forma, a utilização de POA para gerar relatórios automáticos de execução de código se mostra uma solução eficiente e modular, trazendo benefícios tanto para a análise de desempenho quanto para a depuração e auditoria de aplicações Java.
O principal objetivo deste trabalho é demonstrar como a Programação Orientada a Aspectos (POA) pode ser utilizada para automatizar a geração de relatórios detalhados de execução de código em aplicações Java. Este trabalho busca desenvolver uma solução prática utilizando Spring AOP, capaz de capturar tempos de execução e rastrear chamadas de métodos sem impactar a lógica de negócio. O resultado esperado é um sistema modular que facilite o monitoramento de desempenho de aplicações Java, permitindo sua reutilização em diferentes projetos sem a necessidade de alterações significativas no código.
O desempenho de sistemas é um fator crítico no desenvolvimento de software, e a capacidade de monitorar e otimizar o tempo de execução de métodos pode impactar diretamente a experiência do usuário e a eficiência dos sistemas. Muitas abordagens tradicionais exigem que os desenvolvedores adicionem manualmente trechos de código para medir desempenho, o que pode tornar o código mais verboso e suscetível a erros. POA permite resolver esse problema ao separar a preocupação do monitoramento da lógica principal da aplicação, tornando o código mais limpo e modular.
Autores como Ramnivas Laddad (2003), em AspectJ in Action, defendem que a utilização de POA é fundamental para lidar com cross-cutting concerns (preocupações transversais), como monitoramento, segurança e logging, sem interferir diretamente no código principal. Já Scott Oaks (2014), em Java Performance: The Definitive Guide, destaca a importância de técnicas eficazes para medir e otimizar o desempenho de aplicações Java. Ao combinar esses conceitos com a implementação prática do Spring AOP, este trabalho pretende contribuir para a adoção de técnicas mais eficientes de geração de relatórios de execução de código.
Um dos desafios enfrentados por desenvolvedores Java é a necessidade de medir o desempenho de métodos de forma automática e eficiente, sem comprometer a manutenibilidade do código. A inserção manual de logs e métricas pode gerar código redundante e suscetível a erros, dificultando a análise e a otimização de aplicações de grande porte. Embora existam diversas ferramentas externas para monitoramento, nem sempre elas se integram de forma transparente ao código da aplicação.
A hipótese deste trabalho é que a utilização de Spring AOP para a geração automática de relatórios de execução de código permitirá desacoplar a lógica de monitoramento do códigofonte, tornando a solução mais flexível e reutilizável. Além disso, a aplicação de POA facilitará a obtenção de métricas detalhadas de desempenho e rastreamento de chamadas de métodos, sem impactar negativamente a estrutura do código da aplicação.
Foi realizada uma pesquisa bibliográfica sobre Programação Orientada a Aspectos (POA), desempenho de aplicações Java e a documentação oficial do Spring Framework. Foi desenvolvida uma aplicação em Java com o uso de POA, na qual foram implementados mecanismos para interceptar automaticamente a execução de métodos. A partir dessas interceptações, foram capturados dados como o tempo de execução e a ordem das chamadas, que serão organizados em relatórios. O processo foi conduzido de forma a manter a separação entre a lógica de negócio e os aspectos de monitoramento, permitindo observar, na prática, como a POA contribui para a modularização de funcionalidades transversais em aplicações Java.
2 REVISÃO BIBLIOGRÁFICA
Nesta seção, foram apresentados os conceitos fundamentais para a compreensão do tema deste trabalho, a Programação Orientada a Aspectos (POA), a linguagem Java, e o Spring Framework, que oferece suporte à implementação de POA de forma nativa.
2.1 PROGRAMAÇÃO ORIENTADA A OBJETOS (POO)
A Programação Orientada a Objetos (POO) é um paradigma de desenvolvimento que organiza o software em “objetos”, os quais representam entidades do mundo real e contêm tanto dados (atributos) quanto comportamentos (métodos). Esse modelo facilita a modularização e a reutilização de código, permitindo a criação de sistemas mais robustos e de fácil manutenção. Segundo Goetz (2013), a POO promove a clareza e a organização do código, pois encapsula a complexidade dos sistemas em unidades autônomas, facilitando a evolução e a escalabilidade dos projetos.
Além da encapsulação, a POO se fundamenta em outros pilares essenciais, como a herança e o polimorfismo. A herança permite que classes compartilhem atributos e métodos, evitando a duplicação de código e promovendo uma hierarquia lógica entre os componentes do sistema. O polimorfismo, por sua vez, possibilita que métodos com o mesmo nome se comportem de maneiras distintas em classes diferentes, contribuindo para a flexibilidade e a extensibilidade do software. Essa abordagem modular e orientada a objetos é a base sobre a qual tecnologias como POA e frameworks como o Spring se integram, uma vez que facilitam a implementação de funcionalidades transversais sem comprometer a estrutura orientada a objetos da aplicação.
2.2 PROGRAMAÇÃO ORIENTADA A ASPECTOS (POA)
A Programação Orientada a Aspectos (POA) é um paradigma que complementa a Programação Orientada a Objetos (POO), permitindo tratar funcionalidades transversais, como segurança e monitoramento, de forma isolada e sem repetição no código.
De acordo com Laddad (2003), POA oferece um mecanismo para encapsular e modularizar essas preocupações transversais, evitando que fiquem dispersas em diversas partes do código-fonte. Essa abordagem resulta em sistemas mais coesos e de manutenção simplificada, pois cada aspecto pode ser desenvolvido e evoluído de forma independente das demais camadas da aplicação. Além disso, o uso da POA reduz significativamente o acoplamento entre componentes, melhorando a clareza e a testabilidade do software.
Em sistemas desenvolvidos com POO tradicional, preocupações como logging, segurança e auditoria são implementados diretamente dentro das classes, gerando código repetitivo e difícil de modificar. POA resolve esse problema ao introduzir mecanismos de interceptação de métodos e injeção dinâmica de comportamento, permitindo adicionar funcionalidades sem alterar a lógica principal da aplicação (KICZALES ET AL., 1997).
2.3 JAVA E POA
A linguagem Java foi criada pela Sun Microsystems em 1995 e se consolidou como uma das principais tecnologias para o desenvolvimento de software corporativo. Segundo Oaks (2014), Java foi projetado para ser uma linguagem de alto desempenho e segura, mantendo sua portabilidade e escalabilidade para aplicações empresariais.
A arquitetura da linguagem, baseada na Java Virtual Machine (JVM), proporciona um ambiente padronizado e independente de plataforma para a execução de programas. Essa arquitetura permite a utilização de recursos avançados como gerenciamento automático de memória, tratamento estruturado de exceções e execução simultânea de múltiplas tarefas por meio de multithreading. Além disso, o modelo de bytecode e o gerenciamento dinâmico de classes garantem que programas Java possam ser executados em diferentes sistemas operacionais sem necessidade de recompilação.
Outro fator determinante para o sucesso da linguagem é a amplitude do seu ecossistema. Java oferece uma vasta coleção de bibliotecas, APIs e frameworks que simplificam o desenvolvimento de aplicações modulares e reutilizáveis. Essa ampla base tecnológica também contribui para o desenvolvimento de soluções escaláveis e de fácil manutenção, características fundamentais para ambientes corporativos e sistemas que exigem confiabilidade.
Devido à sua estabilidade, maturidade e foco em desempenho, Java é amplamente utilizada em sistemas que exigem controle preciso de execução, sendo especialmente adequada para aplicações que exploram conceitos de Programação Orientada a Aspectos (POA) voltados à análise e monitoramento de performance.
Embora Java tenha sido originalmente projetada sob o paradigma da Programação Orientada a Objetos (POO), a linguagem permite integração com outros paradigmas de desenvolvimento, como a Programação Orientada a Aspectos (POA). De acordo com Laddad (2009), a POA complementa a POO ao possibilitar a modularização de funcionalidades transversais, isto é, aquelas que atravessam diferentes partes da aplicação, como auditoria, logging, segurança e monitoramento de desempenho. Essa modularização reduz a repetição de código e o acoplamento entre os componentes, tornando o sistema mais claro e de manutenção simplificada.
A combinação entre Java e POA é frequentemente viabilizada por frameworks como o AspectJ e o Spring AOP, que fornecem mecanismos para interceptar métodos e aplicar comportamentos adicionais de forma transparente, sem modificar o código-fonte original. Essa integração amplia as capacidades da linguagem, permitindo a criação de soluções mais flexíveis e modulares. Assim, a utilização de POA em Java se apresenta como uma abordagem eficiente para lidar com preocupações transversais, ao mesmo tempo em que preserva a estrutura e a clareza da lógica de negócio.
2.4 SPRING FRAMEWORK E SPRING AOP
O Spring Framework é uma das plataformas mais consolidadas para o desenvolvimento de aplicações em Java, amplamente utilizado por oferecer uma arquitetura modular, flexível e de fácil integração com diversas tecnologias. Criado por Rod Johnson no início dos anos 2000, o framework surgiu como uma alternativa mais leve às soluções corporativas complexas, tornando-se referência no desenvolvimento de sistemas empresariais. Seu design é centrado em princípios como Inversão de Controle (IoC) e Injeção de Dependências (DI), que promovem baixo acoplamento entre componentes e favorecem a escalabilidade e a testabilidade das aplicações.
O Spring AOP é a implementação dessa abordagem dentro do ecossistema Spring. De acordo com Dessi (2009), ele se diferencia por sua simplicidade e pela integração nativa com os demais módulos do framework, permitindo a criação e aplicação de aspectos de maneira transparente. Baseado em proxies dinâmicos, o Spring AOP intercepta chamadas de métodos e aplica comportamentos adicionais, definidos por meio de pointcuts (pontos de interceptação) e advices (ações a serem executadas). Esse modelo torna possível a inserção de lógica auxiliar, como registro de métricas ou verificação de permissões, sem alterar a estrutura do código-fonte original.
Essa característica é especialmente útil na geração de relatórios de execução de código e na medição de desempenho de sistemas, uma vez que permite monitorar tempos de execução, contagem de chamadas e outros indicadores de eficiência. Conforme apontado por Dessi (2009), o uso de aspectos nessa finalidade traz benefícios significativos, como:
• Separação de responsabilidades: O monitoramento é desacoplado da lógica principal.
• Facilidade de manutenção: Alterações no monitoramento não afetam o código-fonte principal.
• Flexibilidade: Os aspectos podem ser aplicados seletivamente em métodos específicos. Dessa forma, o Spring AOP representa uma solução eficaz para o desenvolvimento de sistemas que exigem observabilidade e controle de desempenho, mantendo a estrutura modular e o baixo acoplamento característicos do Spring Framework. Essa integração entre modularidade, flexibilidade e transparência reforça o papel do Spring como uma das ferramentas mais completas do ecossistema Java moderno.
2.5 ALGORITMO DE ORDENAÇÃO
O problema da ordenação é um dos temas mais estudados em ciência da computação, sendo fundamental para a organização e manipulação eficiente de dados em sistemas computacionais. De acordo com Szwarcfiter e Markenzon (2010), a ordenação foi uma das primeiras questões a despertar interesse na busca por algoritmos mais eficientes, uma vez que diferentes métodos apresentam comportamentos distintos conforme o volume e a distribuição dos dados.
A eficiência de um algoritmo de ordenação é geralmente avaliada com base em sua complexidade de tempo e de espaço, o que permite determinar o esforço computacional necessário para processar conjuntos de dados de tamanhos variados. A escolha do algoritmo mais adequado depende do contexto de uso, do tipo de dados e dos requisitos de desempenho da aplicação.
Entre os algoritmos mais conhecidos e amplamente estudados estão o Bubble Sort e o Quick Sort, que se diferenciam tanto na forma de execução quanto na eficiência. O primeiro é reconhecido por sua simplicidade e fácil compreensão, sendo muito utilizado para fins didáticos e experimentais. O segundo é considerado um dos métodos mais eficientes para grandes volumes de dados, graças à sua estratégia de particionamento e recursividade. Ambos servem como referência clássica na análise de desempenho e no estudo da complexidade de algoritmos.
2.5.1 Bubble Sort
O Bubble Sort é um algoritmo de ordenação simples e amplamente difundido, utilizado com frequência no ensino de estruturas de dados devido à sua clareza conceitual e facilidade de implementação. Seu funcionamento consiste em percorrer repetidamente uma lista de elementos, comparando pares consecutivos e trocando-os de posição quando estão fora da ordem desejada.
Segundo Szwarcfiter e Markenzon (2010), em cada passagem completa pela tabela o maior elemento é deslocado para o final, e o processo é repetido até que todos os elementos estejam ordenados. Essa abordagem é intuitiva, porém apresenta um elevado número de comparações e trocas, o que impacta diretamente seu desempenho. A complexidade de tempo do Bubble Sort é O(n²) tanto no melhor quanto no pior caso, característica que limita sua eficiência em conjuntos de dados extensos, embora o torne adequado para demonstrações e experimentos de análise de performance.
2.5.2 Quick Sort
O Quick Sort é considerado um dos algoritmos de ordenação mais eficientes e amplamente utilizados. Sua execução é baseada em uma estratégia de divisão e conquista, na qual um elemento é escolhido como pivô e a lista é particionada em duas partes: uma contendo os elementos menores que o pivô e outra contendo os maiores.
De acordo com Szwarcfiter e Markenzon (2010), o desempenho do Quick Sort depende da escolha do pivô e do equilíbrio entre as partições formadas. Quando o particionamento é equilibrado, a complexidade média alcança O(n log n), o que o torna adequado para grandes volumes de dados. No entanto, em casos desfavoráveis, como quando as partições são desproporcionais, o algoritmo pode atingir complexidade O(n²). Sua estrutura recursiva e seu uso eficiente da memória contribuem para que continue sendo uma das abordagens mais utilizadas em implementações práticas de ordenação.
2.5.3 Análise de Complexidade e Notação Big O
Uma característica fundamental de qualquer algoritmo é o tempo de execução. De acordo com Szwarcfiter e Markenzon (2015), esse tempo pode ser avaliado de forma empírica, pela execução prática com diferentes entradas, ou de forma analítica, por meio de expressões matemáticas que descrevem o comportamento do algoritmo de maneira independente de fatores como computador, linguagem ou compilador.
Para esse fim, utiliza-se a notação Big O, que descreve a ordem de grandeza do tempo de execução de um algoritmo em função do tamanho da entrada. Essa notação permite classificar algoritmos em termos de desempenho no pior caso, melhor caso e caso médio, fornecendo uma forma padronizada de análise. Por exemplo, o Bubble Sort apresenta complexidade de O(n²), enquanto o Quick Sort, em sua análise média, alcança O(n log n).
Essa abordagem analítica é fundamental para comparar o desempenho de diferentes algoritmos de ordenação e compreender o comportamento assintótico de cada método, independente das condições específicas de implementação ou do ambiente computacional utilizado.
2.6 BANCO DE DADOS
Um banco de dados pode ser compreendido como uma coleção organizada de informações que tem como objetivo representar de forma estruturada os elementos e relações de um determinado domínio. Segundo Bittencourt (2004), a principal função de um banco de dados é permitir o armazenamento consistente e a manipulação eficiente de grandes volumes de dados, facilitando a execução de consultas, atualizações e a geração de informações relevantes para diferentes tipos de aplicações.
Os bancos de dados surgiram para organizar e centralizar informações, substituindo modelos baseados em arquivos isolados. Essa centralização trouxe maior integridade, segurança e confiabilidade aos dados, além de padronizar as operações de leitura e escrita.
Um Sistema de Banco de Dados é composto pelo repositório de dados, pelo Sistema de Gerenciamento de Banco de Dados (SGBD) e pelos programas de aplicação que interagem com ele. O SGBD é responsável por intermediar o acesso aos dados, controlando a concorrência entre múltiplos usuários, mantendo a integridade referencial e garantindo que as operações sejam executadas de forma segura e eficiente. Já os programas de aplicação desempenham funções específicas, como a manipulação e o processamento das informações, utilizando o SGBD como interface de acesso.
De acordo com Bittencourt (2004), a adoção de sistemas de banco de dados permite às organizações alcançar um controle mais centralizado e eficaz de seus dados operacionais. A centralização das informações reduz redundâncias, facilita a manutenção e simplifica a integração entre diferentes sistemas. Em contraste, ambientes que não utilizam um SGBD apresentam dados dispersos em múltiplos arquivos independentes, o que torna o controle, a atualização e a consistência das informações tarefas mais complexas e sujeitas a erros.
2.6.1 Tempo de Execução de Processos em Banco de Dados
A medição do tempo de execução de operações em banco de dados é um processo fundamental para compreender o comportamento de desempenho de um sistema de informação. Essa análise envolve a observação de consultas, inserções, atualizações e exclusões de dados, que compõem as transações executadas dentro do Sistema de Gerenciamento de Banco de Dados (SGBD). Segundo Bittencourt (2004), a manipulação dos dados representa a essência funcional de um banco, sendo diretamente responsável pela eficiência e pela confiabilidade do sistema como um todo.
O desempenho de um banco de dados pode ser influenciado por diversos fatores, como o volume de registros, o tipo de índice utilizado, a complexidade das consultas e o nível de concorrência entre usuários. A compreensão desses fatores permite identificar gargalos e otimizar a execução das operações. Em ambientes corporativos, onde há grande quantidade de acessos simultâneos, a análise do tempo de execução torna-se indispensável para manter a estabilidade e a disponibilidade do sistema.
A avaliação de desempenho costuma ser realizada por meio da medição de métricas específicas, como latência, que corresponde ao tempo de resposta entre o envio e o recebimento de uma solicitação, e throughput, que representa a quantidade de transações processadas em determinado intervalo de tempo. O acompanhamento dessas métricas permite observar como o sistema reage a diferentes cargas de trabalho e volumes de dados, oferecendo uma visão detalhada sobre sua eficiência.
2.7 RELATÓRIOS DE PERFORMANCE
Relatórios de performance são instrumentos essenciais para a análise e otimização de sistemas computacionais, pois registram informações detalhadas sobre o comportamento da aplicação em condições reais de execução. Esses relatórios reúnem métricas como tempo de resposta, utilização de CPU, consumo de memória, latência de consultas e tempo de execução de métodos, oferecendo uma visão abrangente sobre a eficiência e o uso de recursos do sistema. De acordo com Oaks (2014), a capacidade de medir e registrar o desempenho de uma aplicação é fundamental para identificar gargalos, compreender padrões de execução e apoiar processos de otimização contínua.
Entre os formatos mais utilizados na geração de relatórios de desempenho, destaca-se o CSV (Comma-Separated Values), amplamente adotado por sua simplicidade, leveza e compatibilidade com ferramentas de análise de dados. De acordo com o Internet Engineering Task Force (IETF, 2005), o formato apresenta uma estrutura de fácil leitura e intercâmbio, ideal para o armazenamento de dados tabulares. Sua organização em colunas delimitadas permite a visualização direta em softwares como o Microsoft Excel e o Google Sheets, facilitando o cruzamento de informações, a criação de gráficos e a comparação entre diferentes execuções. Dessa forma, o uso do CSV em relatórios de performance contribui para a padronização dos registros e para a simplificação do processo de análise, tornando o monitoramento mais acessível e eficiente.
3 DESENVOLVIMENTO
Esta seção apresenta os aspectos técnicos e práticos relacionados à implementação do projeto, detalhando o ambiente de desenvolvimento, os recursos utilizados e as estratégias adotadas para alcançar os objetivos propostos. O foco está na construção de uma solução em Java que permita a geração automatizada de relatórios de execução de código, utilizando os princípios da Programação Orientada a Aspectos (POA). A abordagem busca integrar mecanismos de monitoramento e análise de desempenho de forma modular e não intrusiva, preservando a lógica principal da aplicação. Serão descritas as ferramentas escolhidas, as configurações realizadas e os aspectos implementados para interceptar métodos, medir tempos de execução e rastrear chamadas internas, proporcionando uma visão abrangente do fluxo de execução do sistema.
Os relatórios de performance têm papel preventivo ao permitir o acompanhamento contínuo do comportamento do sistema e a comparação entre versões. Sua geração sistemática aumenta a confiabilidade, a eficiência e a qualidade das aplicações, sendo essencial nas práticas modernas de monitoramento e manutenção de software.
3.1 CONFIGURAÇÃO DO AMBIENTE
O desenvolvimento do projeto será realizado em ambiente Java, com o objetivo de construir uma aplicação capaz de gerar relatórios automatizados de execução de código utilizando conceitos de Programação Orientada a Aspectos (POA). A proposta visa permitir que o monitoramento da execução dos métodos ocorra de forma transparente, sem modificações diretas na lógica de negócio do sistema, o que garante maior organização e modularidade no código.
A escolha da plataforma de desenvolvimento recaiu sobre a IDE IntelliJ IDEA Community Edition, por ser gratuita e oferecer recursos avançados voltados ao ecossistema Java, incluindo integração nativa com ferramentas de gerenciamento de dependências e suporte a projetos Spring. A versão do Java utilizada será a Java 17, uma versão de suporte estendido (LTS) que oferece estabilidade, segurança e compatibilidade com bibliotecas modernas, além de melhorias no desempenho e na linguagem.
3.2 DEPENDÊNCIAS DO PROJETO
O gerenciamento das dependências do projeto será realizado por meio do Maven, uma ferramenta amplamente utilizada no ecossistema Java para automação do processo de build. O Maven permite declarar as bibliotecas necessárias em um arquivo central (pom.xml), garantindo que as versões corretas sejam baixadas e integradas automaticamente ao projeto. Além disso, ele padroniza a estrutura da aplicação e facilita sua reprodutibilidade em diferentes ambientes de desenvolvimento.
FIGURA 1 – DEPENDÊNCIAS DO PROJETO

FONTE: MESMO AUTOR
3.2.1 Spring Context
A biblioteca Spring Context constitui o núcleo do framework Spring e é responsável por fornecer a base para o mecanismo de Inversão de Controle (IoC) e Injeção de Dependências (DI). Esses recursos permitem que os objetos da aplicação sejam criados, configurados e gerenciados de forma centralizada pelo contêiner do Spring, eliminando a necessidade de instanciá-los manualmente no código. Essa abordagem promove alta coesão e baixo acoplamento entre os componentes, favorecendo a modularidade, a escalabilidade e a reutilização de código. O uso do Spring Context também facilita a integração entre diferentes módulos da aplicação, tornando a configuração e a manutenção mais simples e consistentes.
3.2.2 Spring AOP
A dependência Spring AOP (Aspect-Oriented Programming) oferece suporte à Programação Orientada a Aspectos dentro do ecossistema Spring. Essa tecnologia permite a definição de comportamentos transversais, como medição de tempo de execução, tratamento de exceções, auditoria e registro de logs, de maneira modular e independente da lógica principal de negócio. Por meio do Spring AOP, esses comportamentos podem ser aplicados dinamicamente aos métodos da aplicação sem necessidade de modificações diretas no códigofonte. Essa abordagem contribui para uma estrutura de software mais organizada, reduz a duplicação de código e mantém uma separação clara entre as responsabilidades funcionais e não funcionais do sistema.
3.2.3 AspectJ Runtime (aspectjrt)
O AspectJ Runtime (aspectjrt) fornece as classes e recursos necessários para a execução dos aspectos definidos com a tecnologia AspectJ. Essa dependência assegura o funcionamento dos mecanismos que interpretam e aplicam as instruções de interceptação criadas no código. Em conjunto com o Spring AOP, permite a aplicação dos aspectos de forma transparente durante a execução, integrando-se ao ciclo de vida dos objetos gerenciados pelo Spring e possibilitando comportamentos transversais centralizados sem impactar o desempenho da aplicação.
3.2.4 AspectJ Weaver (aspectjweaver)
A dependência AspectJ Weaver é responsável pelo processo de weaving, que insere o código dos aspectos nos pontos definidos do programa, chamados join points. Esse processo pode ocorrer em diferentes estágios, e, neste trabalho, ocorre em tempo de execução, permitindo que métodos anotados com @ExecMonitor sejam interceptados e monitorados dinamicamente. Essa abordagem viabiliza a coleta de métricas de desempenho, como tempo de execução e consumo de memória, de forma transparente e sem alterar a estrutura original do código.
3.2.5 Spring Boot Starter Data MongoDB
O Spring Boot Starter Data MongoDB fornece integração simplificada entre aplicações Spring Boot e o banco de dados NoSQL MongoDB. Essa dependência disponibiliza abstrações de acesso a dados, operações CRUD e suporte a consultas, reduzindo a necessidade de implementação manual e tornando mais ágil o desenvolvimento de aplicações orientadas a dados.
3.3 ANOTAÇÃO DE MONITORAMENTO DE EXECUÇÃO
A anotação personalizada tem como função identificar os métodos que devem ser monitorados pelo aspecto de desempenho. Ela permite classificar o tipo de operação, distinguindo entre métodos que realizam processamento em memória (CPU) e aqueles que realizam operações em banco de dados (BD).
Essa abordagem possibilita que o monitoramento seja aplicado de forma transversal, sem interferir na lógica dos métodos, garantindo a coleta consistente de métricas de tempo de execução e consumo de memória. O atributo type permite gerar relatórios detalhados e realizar análises comparativas de desempenho entre diferentes categorias de operações.
FIGURA 2 – CÓDIGO DA ANOTAÇÃO DE MONITORAMENTO DE EXECUÇÃO

FONTE: MESMO AUTOR
3.4 ASPECTO DE MONITORAMENTO DE EXECUÇÃO
O aspecto de monitoramento é o componente responsável por interceptar, registrar e analisar a execução dos métodos anotados com @ExecMonitor. Sua função é capturar automaticamente métricas de desempenho e informações contextuais da execução, como tempo total, consumo de memória, thread ativa, identificador do processo e status de sucesso ou falha. Essa abordagem permite aplicar o monitoramento de forma transversal e automatizada, sem modificar a lógica original dos métodos, mantendo a integridade do código-fonte e garantindo padronização na coleta dos dados de execução.
O resultado desse processo é armazenado em um arquivo no formato CSV, o qual pode ser aberto diretamente no Microsoft Excel. Esse relatório reúne todas as métricas em colunas estruturadas, facilitando a análise e comparação entre diferentes tipos de operação, como processamento em memória (CPU) e interações com o banco de dados. Dessa forma, o aspecto não apenas automatiza a coleta de dados de desempenho, mas também transforma essas informações em relatórios acessíveis e de fácil interpretação.
3.4.1 Interceptação e coleta de métricas
O método responsável pela interceptação utiliza a anotação @Around para monitorar todos os métodos marcados com @ExecMonitor. No início da execução, são obtidos o instante inicial em milissegundos e a quantidade de memória em uso pela JVM. Também são registradas informações sobre a thread ativa e o identificador do processo Java, permitindo maior precisão na análise de execução.
Durante o monitoramento, o método interceptado é executado normalmente, sem alterar seu comportamento original. Após a execução, o aspecto coleta o instante final e o consumo de memória, calculando a duração total do processamento.
Todos os dados coletados, como data, hora, classe, método, tipo de operação, duração, memória utilizada, thread, PID, status e exceção, são enviados ao método registrarLogCSV, que grava as informações no relatório em formato CSV. Esse processo garante a padronização das métricas e possibilita análises consistentes sobre o desempenho e o consumo de recursos da aplicação.
FIGURA 3 – ASPECTO DE INTERCEPTAÇÃO

FONTE: MESMO AUTOR
3.4.2 Formatação e Registro do Relatório
O método responsável pelo registro das métricas organiza e grava as informações coletadas em um arquivo no formato CSV (Comma-Separated Values). Essa estrutura foi escolhida por sua compatibilidade com ferramentas de planilhas, como o Microsoft Excel, o que facilita a leitura e a análise dos dados de execução.
Durante o processo de escrita, o método verifica se o arquivo já existe e se contém dados. Caso contrário, um cabeçalho padronizado é criado contendo os nomes das colunas que representam as métricas monitoradas. Entre essas colunas estão a data e hora da execução, o instante inicial e final em milissegundos, o nome da classe e do método executados, o tipo de operação, a duração total em milissegundos, o consumo de memória em kilobytes, a thread responsável, o identificador do processo Java (PID), o status de sucesso e, quando aplicável, a mensagem da exceção ocorrida.
Cada registro é gravado em uma nova linha, com os valores separados por ponto e vírgula e precedidos por um apóstrofo. Essa configuração garante que o Excel interprete todos os campos como texto, preservando a integridade dos dados originais. O método é declarado como synchronized, evitando problemas de concorrência e garantindo que múltiplas execuções não causem inconsistência no relatório.
FIGURA 4 – FORMATAÇÃO E REGISTRO DO RELATÓRIO

FONTE: MESMO AUTOR
3.5 MONITORAMENTO DE ALGORITMOS DE ORDENAÇÃO
Os algoritmos de ordenação representam cenários ideais para a aplicação do monitoramento de desempenho proposto, pois envolvem operações intensivas de processamento em memória. Ao analisar o comportamento desses métodos, é possível medir de forma consistente o tempo de execução e o consumo de memória, fornecendo dados relevantes para avaliação de eficiência e comparação entre diferentes abordagens.
3.5.1 Bubble Sort
O método de Bubble Sort foi adaptado para integrar o monitoramento de desempenho por meio da anotação @ExecMonitor, que identifica métodos de processamento em CPU. Cada execução do algoritmo é interceptada pelo aspecto responsável pelo monitoramento, permitindo registrar métricas de tempo e memória utilizadas durante a ordenação. Essa abordagem possibilita observar o impacto do tamanho do array e da complexidade do processamento sobre os recursos do sistema, sem modificar a lógica do algoritmo original.
FIGURA 5 – MÉTODO BUBBLE SORT

FONTE: MESMO AUTOR
3.5.2 Quick Sort
De forma análoga, o algoritmo Quick Sort é monitorado utilizando a anotação @ExecMonitor, permitindo capturar métricas comparáveis às do Bubble Sort. A interceptação das chamadas possibilita identificar diferenças de desempenho e consumo de memória entre os algoritmos, mantendo o foco na avaliação de eficiência de processamento em memória. A utilização do aspecto assegura que o monitoramento seja consistente e não intrusivo, permitindo análises detalhadas sem interferir na execução normal do método.
FIGURA 6 – MÉTODO QUICK SORT

FONTE: MESMO AUTOR
3.6 MONITORAMENTO DE PROCESSOS EM BANCO DE DADOS
O monitoramento de processos em banco de dados possibilita avaliar o desempenho de operações que envolvem acesso e manipulação de informações armazenadas. Essa análise complementa a avaliação de algoritmos de processamento em memória, fornecendo dados sobre tempo de execução e consumo de memória durante operações de persistência.
3.6.1 MongoDB
O MongoDB é um banco de dados NoSQL orientado a documentos, que oferece estrutura flexível para armazenar dados e facilidade de integração com o ecossistema Spring. Ele possibilita a execução eficiente de operações de inserção, leitura e exclusão de dados, atendendo à necessidade de avaliar o desempenho de processos que manipulam grandes volumes de informações. A utilização do MongoDB permite diferenciar claramente os processos que envolvem cálculo e manipulação em memória daqueles que envolvem persistência em banco de dados, fornecendo dados consistentes para análise comparativa de desempenho.
3.6.2 Entidade Produto
A entidade Produto representa os documentos armazenados no MongoDB, contendo atributos que caracterizam o produto, como identificador único, nome e preço. Essa modelagem facilita a execução de operações estruturadas sobre a coleção correspondente, mantendo consistência e integridade dos dados. Além disso, permite a realização de operações em lote, como inserção de grandes quantidades de produtos, possibilitando a coleta de métricas de desempenho durante essas atividades.
FIGURA 7 – CÓDIGO DA ENTIDADE PRODUTOS

FONTE: MESMO AUTOR
3.6.3 Processos em Banco de Dados
O serviço responsável pelos processos em banco de dados contém métodos voltados para manipulação de registros da entidade Produto, incluindo inserção em massa, listagem de todos os registros e exclusão de dados. Cada método é anotado com @ExecMonitor(type = “DB”), permitindo que o aspecto de monitoramento registre métricas de tempo de execução e consumo de memória de forma padronizada.
A inserção de produtos aleatórios demonstra a capacidade de gerar grandes volumes de dados, criando instâncias da entidade Produto e persistindo-as em lote no banco de dados. O método de listagem recupera todos os registros existentes, permitindo avaliar o desempenho de consultas sobre coleções de diferentes tamanhos. Já o método de exclusão remove todos os documentos da coleção, fornecendo informações sobre o impacto de operações de remoção em massa.
Essa estrutura possibilita analisar o comportamento do sistema em cenários com grande quantidade de dados, registrando informações detalhadas no log para avaliação comparativa de desempenho entre operações de CPU e operações de banco de dados. A anotação @ExecMonitor assegura que a coleta de métricas ocorra de forma transparente e consistente, sem interferir na lógica dos métodos.
FIGURA 8 – MÉTODOS DE PROCESSO EM BANCO DE DADOS

FONTE: MESMO AUTOR
3.7 RELATÓRIO DE EXECUÇÃO
O relatório de execução é gerado de forma automática pelo aspecto de monitoramento sempre que um método anotado com @ExecMonitor é chamado. Cada execução de um método monitorado resulta na captura de métricas de desempenho, incluindo tempo de execução e memória utilizada, e na gravação dessas informações no arquivo de log. A geração do relatório ocorre de forma transparente, sem interferir na lógica dos métodos, garantindo que a aplicação funcione normalmente enquanto coleta dados de desempenho de maneira consistente e padronizada.
3.7.1 Estrutura do Relatório
A estrutura do relatório de execução, gerado automaticamente pelo sistema sob o nome relatorio_execucao.csv, foi adaptada para o formato CSV (Comma-Separated Values), o que permite sua abertura e análise direta no Microsoft Excel ou em qualquer outro software de planilhas eletrônicas. Esse formato organiza os dados coletados pelo aspecto de monitoramento em colunas, possibilitando uma leitura clara e uma interpretação automatizada das métricas registradas.
Cada linha do arquivo representa um registro de execução de um método monitorado. As principais colunas presentes no relatório são as seguintes: DATE, que indica a data da execução; TIME, que registra o horário exato; START_MS e END_MS, que armazenam os timestamps em milissegundos do início e término do método; CLASS e METHOD, que identificam respectivamente a classe e o método executado; TYPE, que define o tipo de operação monitorada (como “CPU” para processamento em memória ou “DB” para operações de banco de dados); DURATION(ms), que informa o tempo total de execução em milissegundos; MEMORY(KB), que registra o consumo de memória em kilobytes; THREAD, que identifica a thread responsável pela execução; PID, que indica o identificador do processo Java (JVM); SUCCESS, que mostra se a execução foi bem-sucedida; e EXCEPTION, que descreve brevemente a exceção capturada, caso tenha ocorrido erro.
Ao ser aberto no Excel, o relatório é exibido como uma planilha estruturada, em que cada coluna representa uma métrica específica. O uso do formato CSV, aliado à inclusão de um apóstrofo (‘) antes dos valores, garante que todas as células sejam tratadas como texto, evitando interpretações automáticas de data, número ou formato pelo software.
3.7.2 Análise Comparativa dos Métodos Monitorados
A análise comparativa tem o objetivo de ilustrar as possibilidades de observação e interpretação dos dados obtidos a partir do monitoramento automatizado de desempenho. Os registros gerados pelo arquivo relatorio_execucao.csv permitem identificar métricas como tempo de execução, consumo de memória e ocorrência de falhas durante a execução dos métodos.
A tabela apresentada na Figura 10 foi construída manualmente a partir dos dados coletados no relatório de execução, com o intuito de representar visualmente como essas informações podem ser organizadas e comparadas. Embora não tenha sido gerada automaticamente pelo sistema, ela reflete fielmente os resultados obtidos pelo aspecto de monitoramento, servindo como base para análise e interpretação dos comportamentos observados. Seu propósito é demonstrar, de forma prática, o tipo de estudo que pode ser conduzido sobre os resultados do monitoramento, destacando como diferentes tipos de métodos se comportam em termos de desempenho e consumo de recursos.
FIGURA 9 – TABELA PARA ANÁLISE COMPARATIVA

FONTE: MESMO AUTOR
A comparação dos métodos revela distinções claras entre os dois tipos de operação monitorados: processamento em memória (CPU) e operações de persistência em banco de dados (DB).
Os métodos da classe SortService apresentaram baixo tempo de execução e consumo mínimo de memória, o que reflete a natureza computacional das tarefas de ordenação. O método quickSort() destacou-se pela eficiência, com tempo médio de 17 milissegundos, demonstrando comportamento otimizado em relação ao bubbleSort(), que demandou 57 milissegundos. Ambos completaram suas execuções com sucesso e sem impacto significativo na alocação de memória.
Por outro lado, os métodos da classe ProdutoService evidenciam o custo computacional mais elevado das operações de banco de dados. A rotina inserirProdutosAleatorios() foi a que apresentou o maior tempo de execução (483 ms) e consumo expressivo de memória (34.286 KB), refletindo o esforço de inserção em massa de documentos no MongoDB. O método listarTodos() manteve tempo intermediário (193 ms), relacionado à leitura integral da coleção de produtos, enquanto deletarTodos() mostrou desempenho eficiente, com apenas 55 ms e consumo nulo de memória.
O último registro da tabela representa um erro propositalmente induzido durante a execução de inserirProdutosAleatorios(), simulando uma falha de conexão com o banco de dados. Essa exceção forçada teve como objetivo avaliar o comportamento do sistema diante de condições anormais e verificar a capacidade do aspecto de monitoramento de registrar corretamente erros de execução. O erro de timeout registrado evidencia o papel da anotação @ExecMonitor não apenas como ferramenta de medição, mas também como instrumento de auditoria, capaz de identificar falhas e situações excepcionais em tempo de execução.
Esses resultados demonstram que a aplicação da Programação Orientada a Aspectos em conjunto com o monitoramento automatizado fornece uma visão detalhada do desempenho da aplicação, viabilizando a análise comparativa entre diferentes tipos de operações e a identificação de possíveis gargalos ou instabilidades.
4 CONCLUSÃO
O trabalho demonstrou a eficácia da Programação Orientada a Aspectos (POA) na criação de mecanismos automáticos de monitoramento e geração de relatórios de execução em aplicações Java. A integração entre Spring AOP e AspectJ possibilitou interceptar métodos em tempo de execução e registrar métricas de desempenho sem modificar o código-fonte da aplicação.
A utilização da anotação personalizada possibilitou um controle seletivo sobre os pontos de monitoramento, facilitando a coleta de informações relevantes sobre tempo de execução, consumo de memória e falhas durante o processamento. O relatório gerado em formato CSV, compatível com ferramentas como o Microsoft Excel, proporcionou uma forma prática de análise, permitindo a comparação entre diferentes tipos de métodos e a identificação de gargalos de desempenho.
Os testes com os algoritmos Bubble Sort e Quick Sort, além das operações no MongoDB, mostraram diferenças relevantes no uso de recursos e na eficiência de execução. Esses resultados confirmam o potencial da POA como ferramenta para auditoria, diagnóstico e otimização de sistemas, promovendo maior observabilidade das aplicações.
Em síntese, a proposta apresentou uma alternativa eficiente e extensível para a geração de relatórios de execução em sistemas Java, demonstrando como a separação de preocupações proporcionada pela POA pode ser aplicada de forma prática na análise de desempenho e no aprimoramento da qualidade de software.
REFERENCIAS BIBLIOGRÁFICAS
BITTENCOURT, ROGÉRIO GONÇALVES. Aspectos Básicos de Banco de Dados. Florianópolis, 2004.
DESSÌ, MASSIMILIANO. Spring 2.5 Aspect Oriented Programming. Packt Publishing Ltd, 2009.
INTERNET ENGINEERING TASK FORCE (IETF). Common Format and MIME Type for Comma-Separated Values (CSV) Files. Califórnia: IETF, 2005. Disponível em: https://datatracker.ietf.org/doc/html/rfc4180. Acesso em: 30 out. 2025.
KICZALES, GREGOR ET AL. Aspect-Oriented Programming. European Conference on Object-Oriented Programming (ECOOP), 1997.
LADDAD, RAMNIVAS. AspectJ in Action: Practical Aspect-Oriented Programming. Manning Publications, 2003.
LADDAD, RAMNIVAS. AspectJ in Action, Second Edition. Manning Publications, 2009.
OAKS, SCOTT. Java Performance: The Definitive Guide. O’Reilly Media, 2014.
SZWARCFITER, JAYME LUIZ; MARKENZON, LILIAN. Estruturas de Dados e SeusAlgoritmos. 3. ed. Rio de Janeiro: LTC, 2015.
1Graduando do Curso de Sistemas de Informação Otávio Figueiredo da Universidade de Araraquara- UNIARA. Araraquara-SP. E-mail: ofigueiredo@uniara.edu.br
2Orientador. Docente do Curso de Sistemas de Informação Felipe Diniz Dallilo da Universidade de Araraquara- UNIARA. Araraquara-SP. E-mail: fddallilo@uniara.edu.br
