Spring Framework Para o Desenvolvimento de Aplicações Corporativas

Spring Framework

O Spring Framework é muito popular para construir aplicativos de grande escala. Quando você cria um site de comércio eletrônico que pode ter 50.000 usuários em um determinado momento, a responsabilidade do aplicativo que você está criando muda de patamar. Este porte de site supera rapidamente a arquitetura tradicional de 3 camadas (servidor da web / servidor de aplicativos / servidor de banco de dados). O “site” não é mais um simples arquivo empacotado sendo implantado no Tomcat. Invariavelmente você deverá ter um data center, com uma farm de servidores. Balanceadores de carga na entrada e intermediários, clusters de aplicação, brokers de mensagens, “computação em nuvem”, micro-serviços e outras tecnologias. O Spring Framework não foi construído apenas para esse tipo de ambiente de aplicativos, ele prospera e reina neste mundo.

Ambientes

Ao desenvolver soluções de categoria corporativa, você precisará dar suporte a vários ambientes de implementação. Não pense que irá testar o código em seu notebook e implantá-lo no servidor de produção. Com frequência, na empresa, como desenvolvedor, você nem terá acesso ao ambiente de produção. As empresas que precisam cumprir regulamentações como SOX, PCI e/ou SAS-70 terão equipes especializadas que gerenciarão implantações de código em seus ambientes de teste (QA/UAT) e de produção. Isso é conhecido como segregação de funções. Uma prática mais rigorosa em grandes empresas financeiras como bancos e seguradoras e um pouco menos severas em organizações de varejo como e-commerces. Naturalmente em empresas menores esta será uma praticamente raramente utilizada.

Culturas de desenvolvimento mais modernas realizam construções de CI e implantações automatizadas. As equipes que estão à frente do desenvolvimento moderno de software podem até estar fazendo implantações de delivery contínuo. A implantação contínua é o estado da arte da engenharia de software, mas na realidade é ainda é pouco usado.

Cada um desses ambientes tem suas próprias necessidades de configuração. À medida que o escopo de seu sistema cresce, é provável que a singularidade de cada ambiente também cresça. O Spring Framework tem algumas ferramentas excelentes que são usadas para gerenciar as complexidades do desenvolvimento de aplicativos corporativos modernos. Vamos descrever primeiro quais desafios comuns considerar nos tipos de ambientes que normalmente devem ser suportados em um grande eco-sistema corporativo.

Ambiente de Desenvolvimento

O ambiente de desenvolvimento, normalmente um desktop ou laptop. Preferencialmente o código deve ser capaz de ser executado localmente, sem a necessidade de se conectar a outros servidores na empresa ou de ambiente restrito.

Isso significa:

  • Não pode-se usar um banco de dados externo.
  • Sem interações com outros web-services.
  • Nada de usar um JMS externao. Podemos usar Active MQ localmente.
  • Construção de artefatos de cache local (ex: Maven).

O Grails por exemplo, resultou em um excelente trabalho de suporte ao ambiente de desenvolvimento local. Por exemplo, ao executar o Grails no modo dev, ele cria automaticamente um banco de dados H2 (na memória). O Hibernate é usado para gerar as tabelas do banco de dados com base em suas classes de domínio e bootstrap automaticamente popula as tabelas com dados de teste e desenvolvimento.

Integração Contínua

Os servidores de Integração Contínua podem ser pequenos e complicados, por causa dos diferentes tipos de software de teste que eles acomodam. Podemos ter um projeto que produza um arquivo JAR, que só possui testes de unidade que serão ativados em tempo de publicação. Podemos ter ainda testes de integração, como o Grails, que trazem uma instância incorporada do Tomcat e um banco de dados de memória H2 sem persistência. Testes podem até realizar testes funcionais usando algo como Spock e Geb para interagir com a instância incorporada do Tomcat. Também não é incomum que servidores de IC tenham tarefas de implantação automatizadas, em outro ambiente especializado.

Desenvolvimento

Algumas empresas optam por ter um ambiente de desenvolvimento. Normalmente, esse é um ambiente de produção, como o de um servidor, sobre o qual a equipe de desenvolvimento tem controle. Quando implantado neste ambiente, precisará configurar o aplicativo para interagir com os servidores nesse ambiente.

QA/UAT

QA ou “Quality Assurance” e UAT “User Acceptance Testing” são ambientes para recursos que não são de responsabilidade direta do desenvolvedor, normalmente delegados a uma equipe própria. Em algumas organizações, você pode ter o QA e o UAT, ou você pode ter um ou outro. Se tiver os dois, é provável que a organização tenha Engenheiros de QA formalizados que trabalhem com o ambiente de QA e analistas de negócios que trabalham com o ambiente UAT. Esses ambientes geralmente são gerenciados por uma equipe de gerenciamento de configuração. Às vezes, os desenvolvedores terão acesso ao ambiente, mas geralmente não o farão.

Pre-Produção ou Estágio

Pré-produção ou estágio (armazenamento temporário) é um ambiente de aplicativo que funciona com todos os serviços de produção e bancos de dados de suporte. Esse é um ambiente que permite a implantação do código do aplicativo, mas ao mesmo tempo limita o acesso a este código. Para um site, pode-se ver uma URL especial ou acesso restrito a IPs específicos ou limitado por balanceadores de carga internalizados e restritos.

Esse ambiente não é tão comum, mas algumas organizações o usam. O Facebook é uma empresa que implementa este formato em todas as suas linhas de desenvolvimento.

Produção

Produção é o ambiente que os usuários finais utilizarão. Esse é o principal ambiente transacional e aquele que a corporação e os parceiros de negócios precisam manter operacional o tempo todo.

Resumo

Cada um desses ambientes tem seus próprios requisitos exclusivos. Há diferentes servidores de banco de dados com versões diferentes e, muitas vezes, com diferentes fornecedores. Também diferentes serviços de suporte. Por exemplo, em um site de comércio eletrônico, existe um gateway de pagamento. Em dev, um simulador, e em teste um gateway de teste fornecido pelo provedor de pagamentos e, em seguida, um gateway de pagamento diferente para produção. O mesmo princípio para brokers de mensagem, serviços, servidores de e-mail, servidores de autenticação, etc. Fica claro portanto a complexidade que podem existir. Vejamos a seguir como o Java e o fantástico framework como o Spring conseguem atender todos estes cenários.

Suporte a Vários Ambientes do Spring Framework

O Spring Framework foi desenvolvido desde o início para suportar os desafios de ambientes corporativos complexos. Tem-se vários recursos maduros no Spring para usar no suporte aos desafios de aplicativos de classe empresarial.

Propriedades

O Spring Framework possui excelente suporte para propriedades de externalização. “Propriedades” são valores de string simples que são externalizados em aplicativos e sistemas. No Spring, as propriedades podem ser definidas das seguintes maneiras:

  • Em um arquivo de propriedades tradicional. Isso geralmente é mantido na pasta de recursos e geralmente é chamado de “application.properties”. É por convenção usar .properties.
  • Usando variáveis do ambiente do sistema operacional. Java pode ler valores definidos no sistema operacional como variáveis de ambiente. Muito usado no passado para configurações de banco de dados e integrações com outros módulos. Isso facilita muito que artefatos de construção sejam facilmente transportados entre ambientes. Uma vez configurado, “plugar e brincar”.
  • Variáveis de linha de comando. Ao iniciar qualquer aplcação Java, tem-se a oportunidade de passar variáveis de linha de comando para o programa. Essa é uma maneira prática de tornar artefatos de construção portáveis. Uma palavra de cautela, ao examinar processos em execução em um sistema, às vezes pode-se ler as informações da linha de comando que iniciaram o processo. Portanto, essa solução pode não ser a melhor opção para inicializações e fornecimentos de senhas.

O Spring Framework Support possui várias opções para o fornecimento de valores de propriedade. Uma maneira é usar o Spring Expression Language (SpEL). Falaremos em mais detalhes sobre isso em um post futuro.

Injeção de Dependência

Alterar valores de propriedade é ótimo para coisas como se conectar a um servidor de banco de dados diferente. Mas, muitas vezes, em aplicações de porte empresarial, será necessário alterações comportamentais que estão além das simples alterações de propriedade. Um dos principais recursos do Spring Framework é o suporte da Injeção de Dependência. A injeção de dependência torna o código muito mais modular. Isso implicará naturalmente aderir ao Princípio da Responsabilidade Única. Fazendo injeção de dependência através de Interfaces, facilita em muito a troca e intercâmbio de componentes.

Para ilustrar melhor, digamos que haja uma aplicação que precisa enviar uma mensagem JMS em um determinado evento, como uma compra de cliente. Isso pode acionar um e-mail para o cliente sobre seu pedido e o grupo do Data Warehouse pode querer as informações de compra para suas análises. Para realizar os testes de unidade e testes de integração, pode-se estar usando o Mockito, por exemplo, para fornecer uma simulação. Nestes ambientes implementados, pode-se estar usando o padrão corporativo do MQSeries para troca de mensagens. Mas e quanto a construir CI? Uma instância incorporada do ActiveMQ pode ser uma solução perfeita.

Então, em resumo, este exemplo tem:

  • Um objeto Mockito Mock;
  • 3 configurações diferentes da série MQ;
  • E o ActiveMQ incorporado.

As configurações do MQSeries são fáceis de manipular com configurações de propriedades. A única coisa que muda aqui são os parâmetros de conexão. Este é o caso de uso perfeito para propriedades externalizadas.

Para os testes de unidade, mantem-se os testes de unidade verdadeiros, precisando então gerenciar a injeção de dependência por conta própria. As estruturas de testes, como Mocktio e Spock, facilitam isso.

Realizando testes de integração, uma maneira fácil de gerenciar o Spring Context é por meio da composição da configuração ou usando o Spring Profiles. Cada um é fácil de usar, explicado melhor nas seções abaixo.

1) Composição da Configuração

Os desenvolvedores Spring inexperientes colocarão toda a sua configuração em arquivos xml únicos ou pacotes de configuração. Isso geralmente é um erro, pois limita as opções de configuração. No nosso exemplo, todas as opções de configuração serão suportadas através da composição da configuração. Em seguida, a seletividade importa para uma configuração pai. Basicamente importa a configuração desejada em uma configuração pai e, em seguida, carregando o pai em seu Spring Context em tempo de execução. Esta ainda é uma técnica muito popular para testar onde é muito fácil especificar o contexto do Spring para usar em tempo de execução.

Por muito tempo essa foi a única opção que os desenvolvedores Spring usaram. No Spring 3.1, os perfis foram introduzidos para ajudar a gerenciar diferentes configurações. Como será apresentado na próxima seção, este é um recurso muito poderoso do Spring.

2) Perfis do Spring Framework

O Spring Profiles é um recurso muito poderoso introduzido no Spring Framework 3.1. Os perfis permitem que seja definido o Spring Beans e especificado quando eles devem ser carregados no contexto.

Quando marcado o Spring Bean com um perfil, esse perfil deverá ser configurado ativo para que o bean seja carregado no Spring Context. Isso facilita o gerenciamento do ambiente, pois com isso pode-se simplesmente marcar as diferentes opções com o perfil apropriado e, quando definida esta opção de perfil como ativa, o Spring conectará o Spring Beans apropriado ao aplicativo certo.

Há um perfil especial que é mal documentado, mas muito bom de usar. O perfil padrão. Quando marcado um Spring Bean usando o padrão, este bean é carregado no contexto apenas se nenhum outro perfil tiver sido definido como ativo. Se houver um perfil ativo, o Spring tentará encontrar um bean correspondente a esse perfil primeiro.

O que torna essa opção muito boa é que com ela não precisa definir um perfil ativo na produção. Embora isso seja fácil de usar pode causar algum atrito e confusão com a equipe de gerenciamento de configuração. Por meio do uso de perfis padrão, a aplicação pode ser implementada em produção sem que um perfil ativo seja definido.

Voltando ao exemplo, o ideal é usar um perfil de criação de IC para a configuração do IC, onde deseja-se usar uma instância incorporada do ActiveMQ e, em seguida, configurar a opção do MQSeries usando o perfil padrão. Tendo controle sobre o ambiente de criação de ICs, é fácil especificar um perfil ativo para que os objetos de perfil de criação de IC sejam carregados no contexto do Spring. Quando o aplicativo de exemplo é implementado em outro ambiente, nenhum perfil é configurado para ativo, portanto, os objetos de perfil padrão com a configuração do MQSeries são carregados no Spring Context. Embora estejamos suportando 3 ambientes diferentes com o MQSeries, isso pode ser gerenciado (e deve ser) com propriedades. Isso ocorre porque os objetos do MQSeries permanecem os mesmos, exceto pela configuração do ambiente ao qual o aplicativo está se conectando.

Conclusão

Como plataforma para o desenvolvimento de aplicações, o Spring Framework oferece muitas opções sobre como pode-se compor a aplicação final. Estando acostumado a um desenvolvimento de menor escala, a infinidade de opções de configuração no Spring Framework parecerá um exagero. E pode-se perguntar: Por que você precisaria de tal flexibilidade? Certo? Não, errado! Como mostrado neste post, ao desenvolver aplicativos corporativos, seremos desafiados a dar suporte às necessidades de muitos ambientes diferentes e complexos. Não se está apenas desenvolvendo código no notebook. O ambiente de produção não é mais o único ambiente com o qual se precisa preocupar. Em uma grande empresa, há necessidade imperativa de suportar vários ambientes, com diferentes configurações e necessidades diferentes. O Spring Framework evoluiu ao longo dos anos para suportar as necessidades desafiadoras do desenvolvimento de aplicativos corporativos. Não é de admirar que o Spring Framework seja o framework mais popular a ser usado para desenvolver aplicativos Java de porte empresarial e dentre as demais linguagens de programação uma das poucas a ter um leque tão fantástico de configuração e flexibilidade.

*** A OctalMind é uma empresa especializada no desenvolvimento de sistemas de alta tecnologia.