Revisitando a batalha Spring x Java EE em detalhes

A discussão sobre qual das duas plataformas utilizar no próximo projeto existe faz muito tempo. Inclusive ultimamente teve discussão entre as duas plataformas. Jurgen Hoeller postou sobre a adoção da mais nova versão do Java EE e foi respondido no blog da Oracle.

Olhando um pouco a história, há muito, mas muito tempo atrás, o Java EE era realmente muito complicado e nem era necessário entrar numa discussão, usar o Spring era um caminho mais simples e mais fácil de evoluir, muito melhor. Aí chegou a versão 5 do Java EE e a discussão voltou a ficar um pouco mais quente.

Nessa versão foi introduzida um suporte um pouco melhor a injeção de dependências, mas tudo ainda estava bem centrado nos EJBs. Também foi nessa versão que criar um EJB passou a ser bem mais simples, e ele passou a ser enxergado “apenas” como um objeto com super poderes, ao invés de algo terrivelmente assustador e complicado de configurar. Além disso a parte dos Entity Beans ficou bem mais simples, com a chegada da primeira versão da JPA. Aí veio o Java EE 6 e tudo ficou ainda mais próximo.

Foi introduzida a especificação sobre o container de injeção de dependências, o CDI. Ele passou a ser a estrela da companhia e a ideia é que essa especificação seja o ponto de integração entre todas as outras. A versão 7 seguiu o mesmo ritmo, existem mais componentes ligados ao CDI e outras especificações que ainda careciam de uma configuração mais simples, como a do JMS, ganhou uma nova versão muito mais simples.

Nesse mesmo tempo o Spring também evoluiu. Hoje está na versão 4 e com a versão 5 já planejada, e a configuração ficou muito mais simples. Além disso, eles possuem diversos projetos anexos ao core do framework, que realmente facilitam a vida do desenvolvedor. O auge da facilidade veio com a criação do Spring Boot, onde quase todas as configurações são feitas de maneira automática, restando ao desenvolvedor fazer apenas o estritamente necessário.

Perceba que gastamos mais tempo falando da evolução do Java EE do que do Spring, e isso não vem do fato deles evoluirem mais. É que chama atenção como eles deram uma guinada nos rumos da especificação por conta do terreno que estava sendo perdido.

Passada essa declaração inicial, sobre as evoluções, vamos tentar olhar para alguns pontos específicos que podem nos ajudar a olhar de maneira mais crítica para cada uma das plataformas. Vamos passar pelos seguintes pontos:

  1. Ritmo de atualização
  2. Diferença entre alguns dos principais componentes das plataformas
  3. Integração entre os componentes das plataformas
  4. Documentação
  5. Ambiente de desenvolvimento
  6. Possível uso das plataformas em conjunto
  7. Pragmatismo no momento das escolhas

Ritmo de atualização

Esse é um quesito complicado para a especificação do Java EE. Cada nova especificação precisa passar por um processo de aprovação, para que ela seja integrada ao conjunto das especificações que compõe a plataforma. Enquanto isso, no Spring, cada ideia nova que eles tem, e que acham válida, já pode entrar como um novo componente lançado como alpha, apenas para que o desenvolvedor já possa ir provando.

Você pode visitar a página oficial de projetos ou até mesmo o github deles. Existem projetos que são consolidados, mas também existem vários que os desenvolvedores ainda estão meio por fora, por exemplo: o spring-reactive e o spring-integration-java-dsl. Esses projetos podem ir para frente ou não, mas eles são concebidos e facilmente integráveis ao seu ambiente de desenvolvimento. Para algo entrar na especificação Java EE, de vez em quando, demora bastante tempo.

Vide a especificação que trata de aplicações web Action Based. Desenvolvemos aplicações seguindo essa linha faz anos e só agora vamos ter algo suportado nativamente pelos servidores de aplicação.  A mesma coisa vale para outras especificações, por exemplo o JMS. Há muito tempo que o Spring tem o JMSTemplate para facilitar o uso dessa especificação e só na versão 7 veio algo semelhante no Java EE.

A Red Hat e a Apache até tentam criar projetos para compor o mundo Java EE, como o Arquillian, Forge e o DeltaSpike. Só que falta para eles documentação e, por incrível que pareça, sensibilidade para entender realmente que tipo de atualizações facilitam a vida dos desenvolvedores.

Uma coisa que pode ficar na sua mente é: a preocupação do time do Spring é em criar projetos que possam ser agregados a plataforma e realmente ajudar os mais variados tipos de desenvolvedores. Enquanto que a preocupação do Java EE é de padronizar e não em criar coisas novas.

Diferença entre alguns dos principais componentes das plataformas

Existem certos componentes que são mais comentados dentro das plataformas. Alguns exemplos: segurança, mensageria, web services, framework web etc. Vamos pegar alguns deles para analisarmos.

Segurança

A parte de segurança no Java EE é provida pela especificação JAAS. Por sinal ela é o próximo alvo de melhoria, que vai ser entregue na versão 8 da spec. Toda configuração do JAAS varia de servidor para servidor, e esse é um dos maiores problemas dela. Por mais que você realmente aprenda como ela funciona, uma parte da configuração que você fizer para um projeto, não vai poder ser reaproveitada para o outro, caso você mude de servidor. 

Um outro ponto negativo é o fato de que as proteções dos endereços são feitas no próprio web.xml, algo pouco flexível para certos tipos de projetos.  Um terceiro ponto que eu não gosto é o fato de que usuários, perfis e outros serviços não serem expressados por interfaces dentro da especificação. Então por mais que o seu projeto use JPA, você terá que fazer uma configuração de query para algum servidor, ensinando-o como buscar as informações. Ao invés de implementar uma interface no seu DAO.

Já o Spring Security é completamente baseado em interfaces e possibilita que sua configuração seja feita de modo programático. Por já ter sido pensando de maneira mais orientada a objetos, eles possuem diversos pontos de extensões que podem ser explorados de maneira mais tranquila pelos desenvolvedores.

Mensageria

Caso o seu projeto precise fazer alguma integração baseada em mensageria, você vai precisar ter disponível um servidor dedicado que cuide disso para você. Caso esteja trabalhando dentro de um servidor de aplicação, isso já vem pronto. Com a versão 7 do Java EE, receber e mandar mensagens ficou muito simples. Registrar um tópico ou uma fila se resume simplesmente ao fato de anotar uma classe com as informações devidas. A mesma coisa vale para receber as mensagens enviadas para uma destination.

Em um projeto baseado em Spring, o que mais vai mudar é que você vai precisar saber informações específicas sobre o seu servidor de mensageria para fazer a configuração. Nada que não possa ser aprendido, mas é um passo a mais.  Em relação a receber as mensagens, é tudo muito parecido.

Web Services SOAP

Aqui, de novo, ainda é mais simples dentro de um servidor de aplicação Java EE. Toda infraestrutura necessária já é provida pelo seu servidor de aplicação e tudo isso é exposto para você através de simples annotations. Essa é uma especificação que realmente acertou muito na sua padronização, expor um web service SOAP é muito simples dentro de container Java EE.

Em contrapartida, usando o Spring-WS, você precisa configurar bastante detalhe.  Por exemplo é necessário que seja configurada a Servlet que vai processar as chamadas que vierem via SOAP. Além disso, você precisa configurar o objeto que define o seu WSDL. São estes tipos de detalhes que não queremos ter de nos preocupar em primeira mão e é justamente por esse motivo que eu nunca uso essa extensão deles.

Framework Web

O mundo Java EE, até agora, só nos ofereceu o JSF, que é um framework baseado em componentes e que deu bons passos na sua evolução a partir da versão 2. Para muita gente, o problema dele é que ele é justamente baseado em componentes e isso não pode ser aproveitado quando a sua aplicação demanda um cuidado maior com o front. A boa noticia é que a partir da última versão, criar uma tela com o JSF ficou muito mais flexível e você pode aplicar praticamente todas as boas práticas que você sentir necessidade.

Já o Spring entrega para a gente um framework action based, o Spring MVC. Em geral ele é muito útil para qualquer tipo de aplicação web, inclusive as que o JSF se propõe a resolver. Também é muito maduro e muito bem integrado com todo ecossistema do Spring. O mundo Java EE está produzindo uma nova especificação justamente para este tipo de aplicação, o problema é ela chegar muito tempo depois do Spring MVC e não trazer nada que ele já não te entregue de mão beijada. Para mim, é uma grande falha do mundo Java, pois o Spring MVC não vai seguir a spec e vocês, talvez, terão de se adaptar a uma nova implementação.

Esse é um tópico que me dá um pouco de medo. Realmente não vejo motivo para ter mais de uma versão de framework action based e component based. São ferramentas que usamos muito no dia-a-dia e que deveriam ser as melhores possíveis. Qual o motivo de ter diversidade e esforços espalhados nesses tipos de frameworks, se podíamos investir e ter os 2 melhores do planeta? Ainda não vi um argumento muito forte. Pego exemplos de outras linguagens: Rails no mundo Ruby e ASP.NET MVC para a plataforma .NET. Frameworks super completos e que suprimem a necessidade da criação de outros. Podem até existir, mas não são tão relevantes. No mundo Java, para mim, a exceção foi o Play, apenas porque eles propuseram uma ferramenta realmente diferente, apesar de ser fortemente inspirada pelo Rails.

Outras tecnologias/especificações

Poderíamos ainda debater sobre outros componentes. Por exemplo, o Spring MVC consegue fazer o papel do JAX-RS numa aplicação, apesar deles também terem criado o Spring Hateoas. Temos o Spring Data JPA que facilita muito a utilização da JPA. O último é mais uma junção de forças enquanto que o primeiro, realmente não causa um impacto tão grande na sua vida. A ideia era pegar algumas das principais para olharmos e também para deixar a seguinte mensagem: tudo está muito parelho, use uma tabela de decisão calçada por uma visão pragmática para você tomar a melhor decisão.

Integração entre os componentes das plataformas

Aqui o Spring ainda está na frente. Como tudo, desde sempre, gira em torno do core, todas as extensões se integram de maneira transparente. Você coloca o Spring Security e qualquer objeto gerenciado pode ser protegido. Você adiciona o Spring Cache e o retorno de qualquer método pode ser guardado no cache. Adicionamos o Spring Social e já temos uma integração com o Security, para que o usuário logado já entre no contexto.

No mundo Java EE ainda precisamos fazer, muitas vezes, com que os componentes se integrem manualmente. Por exemplo temos o JAAS, mas não temos nada que possamos usar para proteger os trechos das páginas. Temos a especificação de Cache, mas ela não se integra com os métodos dos beans gerenciados pelo CDI. Temos o CDI, mas ainda nem todos os componentes podem ser injetados através dele. É necessário uma integração fina entre tudo, tem que funcionar como um projeto só, não como vários projetos separados suportados pelo servidor de aplicação.

Documentação

Documentação deveria ser o ponto de partida para o aprendizado de qualquer coisa. Esse é um outro quesito que o Spring leva vantagem. A documentação oferecida pelo site vai bem além de uma visão superficial da tecnologia. Contém exemplos de uso e vários dos projetos possuem um github com vários exemplos que podem ser facilmente importados e analisados pelo desenvolvedor. Com um pouco de paciência, você acaba achando a maioria das coisas que precisa na própria documentação.

A Red Hat até tenta fazer isso com as extensões que ela produz, como o Swarm ou o Keycloak, mas não cria exemplos de uso para todas as implementações de especificações que estão dentro do servidor. A mesma coisa acontece para todos e, dessa forma, o desenvolvedor tem que ficar caindo em fóruns e tutoriais para conseguir aprender.

Ambiente de desenvolvimento

Para mim essa sempre foi uma das principais dificuldades da plataforma Java. Apesar de termos boas IDEs, como o Eclipse e o IntelliJ, um bom ambiente de desenvolvimento vai muito além disso. Vamos pegar algumas necessidades que podemos ter:

  1. Geração de configurações que se repetem entre projetos
  2. Geração de códigos de negócio que se repetem entre os projetos
  3. Deploy e redeploy das aplicações em ambiente de desenvolvimento
  4. Geração do ambiente necessário para a execução da aplicação
  5. Execução de testes e diferenciação por ambiente

Configurações e códigos repetitivos

A maioria dos projetos Java passam sempre pelos mesmos problemas. Vou até tirar da jogada que vários dos projetos fazem uso de outras ferramentas, principalmente as ligadas ao front, como Gulp e afins. Apesar de claramente terem seu valor automatizando outras tarefas, trazem um pouco mais de complexidade para o ambiente de desenvolvimento.

Caso você tenha optado pelo pacote comum de desenvolvimento de aplicações baseadas no Java EE, você vai encontrar algumas das dificuldades citadas acima. Precisa configurar o JSF, é necessário criar o faces-config.xml. Vai usar o JAAS dentro do Wildlfy, precisa ter o jboss-web.xml no seu projeto. Quer usar o JAX-RS, é necessário criar a classe que indica o contexto raiz dos seus serviços. A mesma coisa vale para códigos de negócio que se repetem, como tudo necessário para escrever um CRUD, listeners do JMS etc. Fazer da primeira vez é interessante, na segunda você realmente aprende e partir da terceira já fica repetitivo. A Red Hat se movimentou e criou um projeto bem interessante, chamado Jboss Forge, que automatiza um monte dessas coisas. Junto com outros desenvolvedores da Caelum, também criei um projeto para facilitar isso, o SetupMyProject, confira aqui.

Apesar de gerar ser uma boa coisa, o melhor era nem precisar ficar configurando a maior parte destas coisas. E aí o Spring fez uma jogada de mestre e criou o projeto chamado Spring Boot. Eles colheram tudo que a gente mais usa e decidiram por uma pilha de tecnologias. Basta que um jar seja adicionado no classpath e toda configuração de infraestrutura é feita automaticamente, por classes deles. Por exemplo, quer usar um servidor como o Redis para guardar seus objetos cacheados, adicione o jar do mesmo e o Spring Boot já permite que você receba injetado a conexão com ele. Isso porque o Redis tem uma porta de funcionamento default e também vem sem proteção com senha por padrão, para que me obrigar a configurar? Outro ponto interessante, é que ele traz suporte aos servidores embedded. Caso use ele, acabou a necessidade de obrigar os devs a ficarem baixando tomcat ou jetty e ainda terem que ficar aprendendo a configurá-los. Colocou o jar no classpath, ele já vai usar o servidor selecionado e rodar o seu projeto.

Deploy e redeploy das aplicações em ambiente de desenvolvimento

Além disso o Spring Boot trouxe uma extensão que permite que novos redeploys em desenvolvimento sejam feitos, na maioria das vezes, em menos de três segundos, é o Spring Boot dev tools. Tudo isso junto deixa você mais produtivo, e vai contar no fim do mês para você e para a empresa que você trabalha.

Geração do ambiente necessário para a execução da aplicação

Para finalizar, gerar o arquivo de deploy é algo que precisamos o tempo inteiro. O Spring Boot já criou uma extensão para o Maven que nos permite gerar um jar que pode ser executado direto, sem a necessidade de instalar e configurar um servidor em produção, ótima opção para a maioria dos projetos.

Execução de testes e diferenciação por ambiente

Uma ajuda nesse tópico realmente pode ser útil durante o desenvolvimento. Por exemplo, realizar testes de integração é uma tarefa bem comum para a gente. Como verificar se suas JPQL estão funcionando? Não tem jeito, você é obrigado a bater no banco de testes e também a limpá-lo entre cada execução de testes. No mundo Spring isso está pronto enquanto que para o mundo Java EE, o mais próximo que temos é o Arquillian. A diferença é na complexidade do setup, o Arquillian exige muita configuração e tudo só para emular o container, não tem nada que efetivamente te ajude a controlar melhor os testes.

A mesma diferença vale para diferenciar os ambientes. Pensando no caso mais simples, precisamos de um DataSource para desenvolvimento e outro para produção. O mais perto que temos disso no Java EE é a parte alternatives do CDI. Só que é tudo baseado em XML e você precisa trocar a configuração do beans.xml. O DeltaSpike tenta ajudar nisso, permitindo que você use anotações específicas dele para informar quais classes devem ser gerenciadas em função do ambiente. O problema é que o Servidor de Aplicação não sabe nada sobre isso e mais uma vez perdemos a integração. Em contrapartida, a parte de Profiles do Spring é muito simples e bem integrada a toda a plataforma.

Possível uso das plataformas em conjunto

Essa é uma daquelas coisas que muitas vezes são rechaçadas na arquitetura do projeto. Não existe nenhuma regra do mundo que te faça optar por um caminho e, obrigatoriamente, ter que abandonar o outro. Por exemplo, o Spring Security é completamente baseado em Servlet Filter, o que faz com que ele seja plugável em qualquer aplicação web Java que rode sobre um Servlet Container. Só que você vai ficar limitado a proteger só as suas URLs, pois os beans estarão sendo gerenciados pelo CDI/EJB.

Vamos agora pensar numa aplicação baseada no Spring, você vai querer usar o Spring Data, por exemplo. Só que para isso, precisa do EntityManager provido pelo servidor de aplicação, já que o DataSource está configurado pelo servidor. Você pode configurar o Spring para buscar a referência para o EntityManager através da JNDI. O mesmo vale para o controle transacional! Essa é uma característica do Spring, ele não evita o que está pronto num servidor Java EE, ele simplesmente te dá outras opções.

Para fechar essa parte, tanto o Spring quanto qualquer implementação do CDI, possuem classes que representam o container dos objetos gerenciados. Se você estiver encurralado, por exemplo dentro de uma classe gerenciada pelo CDI precisando de acesso a algum objeto gerenciado pelo Spring, você pode fazer uso dessas classes. Caso tenha ficado curioso, dê uma olhada aqui para ver como acessar o container do Spring de maneira programática ou aqui para ver como acessar o container do CDI.

Pragmatismo no momento das escolhas

Supostamente isso não precisaria ser destacado. De todo jeito acho que vale o comentário, decida pela plataforma pautado pelas suas necessidades e as habilidades do time em cada uma delas.

Para mim, a plataforma do Spring ainda está em vantagem por conta que eles podem fazer tudo integrado ao framework, ao contrário do Java EE que precisa fazer tudo voltado para a especificação. Para a nossa sorte o Java EE está avançando muito e, como disse, a versão 7 está muito melhor e mais simples.

Um outro ponto que você precisa levar em consideração é que a decisão da plataforma base nem sempre está nas mãos dos programadores. Você pode acabar se vendo obrigado a usar uma plataforma apenas porque o sistema existente já faz uso dela, então conhecer as duas te deixa mais preparado para a maioria dos projetos que você vai enfrentar.

Como vimos, por mais que elas sejam duas plataformas que muitas vezes tentam atingir o mesmo propósito, você pode considerar em juntar as forças, quando for necessário. Deixe sempre essa possibilidade em aberto!

Aprendendo mais

Não deixe de conferir nossos cursos e livros sobre esses assuntos. Na Casa do Código você pode encontrar dois livros sobre Spring, o meu e o de Henrique Lobo. Também pode encontrar livros que tratam sobre o Java EE. Tem também especificamente sobre o CDI e sobre JPA e JSF.  Caso prefira fazer aprender através de aulas presenciais, a Caelum também já disponibiliza os treinamentos, você pode conferir a ementa sobre o Spring e sobre o Java EE. Em breve ainda teremos os mesmos treinamentos no Alura!

 

30 Comentários

  1. Rodrigo Ferreira 01/12/2015 at 10:29 #

    Oi Alberto,

    Parabéns!!! Excelente texto!
    Super completo e sem querer direcionar para um ou outro, mas sim mostrar e discutir os trade-offs entre ambos.

    No curso de Arquitetura sempre gasto um bom tempo sobre o assunto Spring x Java EE, discutindo os problemas do Java EE antigamente, e também comentando sobre as melhorias e simplicidade que vem surgindo nas últimas versões, além de também discutir sobre a facilidade/simplicidade e problemas gerais do Spring.

    Realmente hoje ambas as plataformas estão bem maduras e acredito que acaba mais sendo uma questão de gosto/costume escolher qual delas utilizar. Claro que cada uma tem suas facilidades e dificuldades em certos cenários, mas o ideal seria estar a aberto a trabalhar com qualquer uma delas, ou até mesmo, como você citou, utilizar as duas em conjunto quando fizer sentido, aproveitando assim o melhor dos dois mundos.

    Abraços!

  2. Icaro 01/12/2015 at 11:11 #

    Existem aspectos nao tecnicos mas que influem tambem, e diria que os aspectos a seguir estao hoje mais importantes que os tecnicos pra se definir entre as 2 plataformas: haver profissionais qualificados, haver bons materiais e bons cursos, popularidade de uso (o que ajuda a encontrar comunidades e auxilio mutuo).

    pois é diferente uma caelum ter liberdade de experimentar varias coisas etc, a uma empresa que nao muda de tecnologia com tanta facilidade, e vai geralmente preferir solucoes maduras e com bom porte de pessoal capacitado no mercado…

    o mesmo vale para adotar soluções não tão difundidas: play, rails, grails…

  3. Alberto Souza 01/12/2015 at 11:48 #

    Opa Rodrigo, a ideia era dar uma visão crítica, mesmo que em alguns pontos eu deixei vazar a minha opinião sobre as soluções.

    Oi Icaro, a cultura da empresa e o quão flexível ela é para mudar de plataforma influencia sim, com certeza. Só não é um aspecto técnico… Como as duas plataformas se preocupam em manter a compatibilidade com as versões anteriores, o melhor para as empresas era evoluir junto. Pensando pelo lado do Java EE, o que incomoda um pouco é a demora dos grandes servidores em oferecer o suporte pago as versões mais recentes.

    Abraço!

  4. Henrique Lobo Weissmann 01/12/2015 at 14:21 #

    Sempre achei bastante curioso o uso do termo “batalha” quando se fala de Spring e Java EE.
    Quem usa este termo normalmente ignora um aspecto essencial do Spring: nunca foi seu objetivo substituir o Java EE, mas sim complementá-lo.

    Spring é e sempre foi um “framework para o Java EE” e não um substituto ao mesmo.

    Você não para de usar o Java EE ao adotar o Spring: na prática você apenas o usa como uma plataforma em cima da qual o Spring é baseado.

    Partindo deste princípio, toda a discussão perde o sentido, pois você não precisa abrir mão de absolutamente nada do Java EE ao usar o Spring. Não existe “possível uso das duas plataformas em conjunto”. Se você trabalha com Spring, na prática já está fazendo isto.

    As questões envolvendo mensageria também não batem, pois uma aplicação Spring pode ser implantada em um container de aplicação. Então a questão neste ponto não seria o Spring e O Java EE, mas sim se estamos usando um container servlet (Tomcat) ou um servidor de aplicações completo, como Wildfly.

    A questão sobre os webservices SOAP, também está equivocada. O que está em questão não é o uso ou não das anotações do JAX-WS (elas podem ser usadas de forma transparente em um projeto baseado em Spring), mas sim se você vai adotar uma abordagem “design first” do seu serviço ou não. O Spring WebService adota esta abordagem. Como pode ver, é outro ponto aqui.

    Sobre o ambiente de desenvolvimento: realmente, mas este é um problema que já foi resolvido com Maven há pelo menos uma década, então não é mais um problema tão sério assim, especialmente se for levar em consideração que a integração das IDEs com os servidores de aplicação não é mais um problema há pelo menos o mesmo tempo. É curioso não citar, por exemplo, que alguns servidores de aplicação, como o JBoss AS e o Weblogic inclusive oferecem IDEs próprias que já trazem ao desenvolvedor um ambiente COMPLETO de desenvolvimento, que te poupa muito trabalho e, curiosamente, baseado em padrões abertos como Maven, Gradle, etc.

    Diga-se de passagem, é importante mencionar que não é só o Spring Boot que nos fornece uma solução (como o plug-in Maven) para ajudar no deploy e redeploy. Basicamente todo container de aplicação oferece alternativas similares.

    Sobre “configurações e códigos repetitivos”, é curiosa algumas omissões no texto: o que vêmos é a aplicação do conceito de convenção sobre configuração que, pensando apenas em Java EE, já vimos ser aplicado no passado e com sucesso. Exemplo: JBoss Seam (dando um exemplo bem antigo).

    Aliás, este texto é em si bastante tendencioso quando fala sobre a qualidade da documentação: o tutorial de Java EE padrão, por exemplo, é extremamente bom e *muita* gente aprende por lá. Isto sem mencionar que praticamente todos os servidores de aplicação também oferecem documentações excelente (a do Weld, por exemplo, é fascinante e uma das melhores coisas que já li sobre os conceitos de inversão de controle e injeção de dependências). A documentação do Spring é excelente? Sem dúvidas, mas a dos outros componentes também: basta ter um pouquinho de boa vontade pra procurar (veja as que citei).

    Estes foram alguns dos pontos que encontrei no texto. É importante tentar frear esta nossa “paixão” quando o assunto são tecnologias, pois ela nos cega em relação ao todo no qual estas se encontram. Outro ponto importante: saber diferenciar Spring Framework de Spring Boot. O primeiro vai muito além do segundo.

    E pra provar que não fui tendencioso, também tenho um livro publicado sobre Spring pela mesma editora: http://www.casadocodigo.com.br/products/livro-spring-framework

    (livro que, aliás, mostra exatamente isto que coloquei neste comentário)

  5. Alberto Souza 01/12/2015 at 15:05 #

    Oi Henrique, muito legal seu comentário e deixou o texto bem mais rico. A parte do Web Service SOAP foi bem interessante, já que realmente essa extensão do Spring ataca justamente o estilo de solução que você citou.

    Em relação a batalha, olhando pelo prisma do Spring, você tem razão. Dentro do mesmo texto é comentado que ele não evita, apenas fornece outras opções para cenários parecidos. Já ele ser um framework para o Java EE, é um ponto de vista seu, que eu respeito. Acho que se realmente fosse, ele seria uma implementação do CDI e aí tudo seria realmente integrado, funcionaria como uma super extensão do Java EE.

    O ambiente de desenvolvimento, pelo menos para mim, vai bem além de configurar o Maven. O Spring Boot deixa diversas configurações de bibliotecas e frameworks muito simples. Você vai usar o driver do Redis, ele já configura todos os defaults para você, mesma coisa vale para a JPA no caso de estar fora de um container Java EE. Aí você pode pegar qualquer extensão dele… No texto até tratamos o Spring Boot como uma “jogada de mestre” deles, para deixar as configurações mais fáceis. As IDEs especializadas ajudam, com toda certeza. Assim como o Forge e qualquer outro projeto nessa linha.

    A documentação, mais uma vez, é uma questão de opinião. Para a maioria dos módulos do Spring existe uma boa documentação e vários exemplos mantidos por eles no Github. Acho a documentação deles mais extensa do que a da maioria dos projetos de implementação do Java EE. Também acho que é mais detalhada e organizada.

    Com certeza não devemos ser apaixonados, e o texto fala bem sobre isso. Mais uma vez, obrigado pelo ótimo comentário. Seu livro também foi adicionado na última seção do texto, falha minha não ter colocado.

  6. Raphael Lacerda 01/12/2015 at 20:35 #

    Meu rei!! não faltou os links para os próprios textos do blog da caelum falando sobre essa batalha?

    Pois aqui é uma revisitação da revistação!!

    grande abraço

  7. Alberto Souza 01/12/2015 at 23:44 #

    Opa,

    Segue o link de outro post sobre o tema aqui no blog => http://blog.caelum.com.br/java-ee-versus-spring-retomando-a-discussao/

  8. cviniciusm 03/12/2015 at 08:29 #

    No artigo “How not to hate Spring in 2016” (http://spring.io/blog/2015/11/29/how-not-to-hate-spring-in-2016) é citado “No seu coração, Spring é um framework de integração. Ele provê um modelo de programação consistente através de muitas tecnologias diferentes” . E cita como é difícil manter essa integração. De um lado, Spring Framework fornece os ingredientes e o Spring Boot é o bolo pronto. Assim, percebe-se claramente o movimento de independência do Spring. De outro lado, o Java EE suprindo suas deficiências ao longo do tempo (que antes supridas pelo Spring). Portanto na minha opinião, para 2016 em diante, escolha um (Java EE ou Spring) e seja vencedor ?

  9. Marcelo 03/12/2015 at 13:24 #

    Melhor de tudo é que é uma batalha em que ambos evoluem. 😀
    Belo post.

  10. Rafael Augusto 08/12/2015 at 12:33 #

    Muito bom o artigo Alberto, está de parabéns! Gostei muito da visão dos dois mundos e das comparações. Já trabalhei um pouco com o ambiente Spring e atualmente trabalho com Java EE, ambos são muito bons e gosto muito dos dois, eu também não vejo o porquê de ignorar um ou outro, pois cada um possui suas vantagens e desvantagens. Como você mesmo disse: “decida pela plataforma pautado pelas suas necessidades e as habilidades do time em cada uma delas”. Concordo com isso e na prática, para mim pelo menos, tem funcionado perfeitamente.

  11. Alain Oliveira 10/12/2015 at 09:58 #

    Parabéns pelo post Alberto!

    Assim como o Henrique citou, sempre achei toda e qualquer “batalha” entre frameworks/linguagens de programação um tanto quanto equivocadas. Sempre acreditei da questão da solução por necessidade: qual solução seria melhor aproveitada para qual necessidade.

    Como alguns aqui, venho dos tempos nebulosos do Java EE e sempre busquei alternativas a ele. Tem alguns meses fiz vários testes para tentar rever meus conceitos sobre ele (inclusive as novas especificações tem sido abordadas nas últimas edições da Java Magazine) e hoje, para a necessidade da minha solução, não trocaria o Spring.

    Hoje utilizo o Spring pois, de modo geral, preciso de um ferramenta madura para segurança, fácil integração e banco de dados orientado a grafos. Achei tudo isso dentro do Spring, sem precisar buscar nenhum outro framework para a necessidade que tenho.

    Achei muito interessante a abordagem mas, com um olhar um pouco mais profundo, vi que de certa forma parece “pender” para o lado do Java EE, o que acredito ser natural pois eu também o faria para o lado do Spring se fosse eu o autor. Mas falando mais do mesmo, sempre tem a solução por necessidade.

    Mas enfim, parabéns pela abordagem e pelo novo livro. Ainda somos extremamente carentes em literatura de qualidade nas diversas áreas de tecnologia no nosso idioma.

    Grande abraço!

  12. Michell 10/12/2015 at 12:11 #

    Muito bom! Spring bem à frente. Aqui na empresa estamos caminhando para o uso 100% do Spring.

  13. Alberto Souza 10/12/2015 at 12:57 #

    Oi Alain,

    Na verdade até comento no post que a plataforma provida pelo Spring ainda, para mim, parece mais madura e mais integrada. O Java EE caminha a passos largos para ficar mais integrado ainda! O segredo é fazer com que tudo passe pelo CDI.

  14. Alain Oliveira 10/12/2015 at 13:47 #

    Oi Alberto,

    Sim, no meu ponto de vista este é o ponto chave: maturidade.

    Tive a sensação de evolução do Java EE, principalmente pelos últimos artigos/exemplos da Java Magazine que conferi onde a utilização de CDI é fortemente abordada. Contudo, o Spring já faz isso “de praxe” há muito tempo. É mais maduro não só nesse como em alguns outros pontos. Se abrirmos o leque de funcionalidades disponibilizadas pelo Spring e a integração entre elas essa maturidade se mostra ainda maior.

    Acredito que quem hoje questiona o uso do Spring, assim como quem questiona o uso do Java EE, ainda que sem intenção, vai opinar basicamente pelo que é mais confortável pra ele pois, independente de maturidade, sabemos que na maioria dos casos nós programadores adotamos certas linguagens/frameworks por gosto, e não necessidade. Por vezes “adaptamos” a necessidade para a linguagem preferida ao invés de escolher a linguagem/framework ideal para certa necessidade.

    Por Java ser tão grande existem debates como esse (esses dias me peguei em um sobre objetos/classes anêmicos – que também acho outra bobagem) mas isso já é outro assunto…

    Abraço e parabéns!

  15. Guilherme 10/12/2015 at 16:02 #

    Bem legal o texto, acho interessante, mas gostaria mesmo que o java ee mvc 8 fosse igual ao VRaptor, ai seria bom. Atualmente estou optando pelo VRaptor ou pelo Vertx, principalmente esse ultimo que é bastante flexível.

  16. Fernando Boaglio 10/12/2015 at 18:21 #

    Interessante artigo, mas concordo com as colocações do Henrique Lobo… os dois são mais amigos do que inimigos, diferente da clássica luta de UFC do EJB vs Hibernate.
    Eu vejo algumas ferramentas beneficiaram ambos os lados, como os archetypes do Maven que entregam uma aplicação pronta, e alguns plugins, como o tomcat7-maven-plugin, que sobe sua aplicação numa boa sem precisar instalar nada.

  17. Manoel Vicente Pereira Neto 11/12/2015 at 11:51 #

    Parabéns pelo post, achei o texto bem rico com informações bem interessantes!

  18. Marcelo Daniel 21/12/2015 at 13:26 #

    Pra não alongar muito concordo 100% com o que o Lobo escreveu. Só pra adicionar, algumas destas “vantagens” que foram citadas podem ser válidas para ambiente de desenvolvimento, já para produção é outra história. Já desenvolvi bastante tempo com spring e a qualidade do produto é inquestionável. Usar a especificação JEE é outra excelente alternativa. Muitos devs que andam opinando por aí sequer sabem o que é um servidor de aplicação, quais recursos ele oferece e como otimizá-lo para um ambiente de produção. Não sabem o que é balanceamento de carga, cluster, replicação ou redundância. Nunca vi e desafio qualquer um a colocar em produção um framework que gera tudo automagicamente sem qualquer otimização. Projetos sérios e de importância não dá pra fugir de configuração de ambiente e servidores (seja ele tomcat, jetty, wildfly, weblogic, websphere…). Atualmente meu ambiente de produção é em boa parte padrão JEE. Tenho total controle das apis que estão no servidor e meu deploy não leva consigo uma centena de jars de dependência o que faz toda diferença no momento de fazer um upload para a cloud por exemplo. Só pra não citar achei que o artigo subestimou bastante o poder do arquillian, ele é bem mais do que simulação de container. Além do mais uma coisa fabulosa que acho no spring é que dá pra fazer a mesma coisa de várias maneiras. Ao mesmo tempo que o que mais detesto no spring é exatamente porque dá pra fazer a mesma coisa de várias maneiras, junte isso num time e verá quantas variações podem existir pra casa solução ao passo que JEE tenta padronizar mais este tipo de coisa. Não existe paixão neste ramo, uso o que for mais conveniente, por isso minha escolha é bem simples. Para o que preciso o JEE me atende? se sim sigo com ele, se necessitar de uma feature que só o spring tenha utilizo spring, simples.

  19. Tiago de Freitas Lima 22/12/2015 at 23:08 #

    Sobre a questão da “batalha”, tenho uma opinião próxima à que o @henrique.lobo colocou: o Spring nunca quis substituir o JEE, nem nenhuma das especificações do JEE. O Spring foi criado com o objetivo de complementar e simplificar o desenvolvimento com Java, e me parece que essa ainda é a motivação principal do framework.

    Me lembro de ter lido uma entrevista do Rod Johnson (o criador do Spring) a respeito daquele livro famoso dele, o “Expert One One J2EE”, e lhe foi perguntado o que ele gostaria que todo desenvolvedor tivesse aprendido com o livro. A resposta dele foi: “usar o J2EE para construir a solução mais simples possível para um determinado problema”. Essa sempre foi a proposta do Spring.

    Isto posto, na minha opinião, eu vejo o Spring como um concorrente não do JEE em si, mas sim do modelo de programação baseado no application server como ambiente de execução. O Spring sempre tentou oferecer um conjunto de soluções FORA de uma infraestrutura complexa como é o servidor JEE, de modo que a aplicação possa ser deployada em um simples web container como o Tomcat ou o Jetty. Esse é um ponto que considero chave e dificilmente vejo sendo levantado em comparações “JEE vs qualquer outro”. Acho curioso que em software nós sempre falamos de “reduzir a complexidade”; por que com a infrastrutura deveria ser diferente? Manter um Wildfly ou um Glassfish (que dizem ser “leves”) é tão simples quanto manter um Tomcat?

    Após o surgimento do Rails, vários frameworks tentaram implementar o conceito de “framework full stack”. O framework em questão irá oferecer à aplicação um conjunto de (possíveis) soluções para os requisitos não funcionais (segurança, acesso a banco de dados, expor recursos por http, etc). Acho engraçado que o Java EE tenha uma proposta que é quase o oposto: é o “ambiente de execução full stack”. A aplicação não utiliza um framework que lhe oferece recursos, e sim é dependente dos recursos estarem disponíveis no ambiente de execução (o servidor JEE). Eu não vejo sentido nessa abordagem. Frameworks como o Spring Boot, o Play!, o Ratpack, o Dropwizard, trabalham com um conceito completamente diferente (um jar executável que possui TUDO que a aplicação necessita, inclusive o web container); o Grails, que é um framework full stack que oferece muitos e variados recursos, gera um war que pode ser deployado em qualquer web server Java simples, e esse war já conterá tudo que a aplicação necessita pra funcionar. Não há nenhuma necessidade do ambiente de execução fornecer o que quer que seja.

    A RedHat possui um projeto com essa abordagem (o Wildfly Swarm), mas a mim soa como uma proposta específica deste fabricante; claramente, o JEE possui uma proposta diferente.

    O colega @marcelo.daniel comentou que poucos desenvolvedores hoje conhecem o que é um servidor de aplicação. Achei essa observação curiosa, pois o conceito de “servidor de aplicação” que temos em Java soaria estranho para, digamos, um desenvolvedor Ruby ou Python. Será que eles não conhecem nada de “balanceamento de carga, cluster, replicação ou redundância”? Em outras palavras: será que eles não conseguem se virar sem um servidor de aplicação? Por que será que o conceito de “servidor de aplicação”, tal qual existe em Java, é tão fragil (ou inexistente) em outras plataformas?

    Outra questão são as tendências modernas de desenvolvimento de software. Tomo como exemplo os microserviços. Não é segredo que a infraestrutura de execução do JEE (os servidores) não foi construída com a idéia de aplicações distribuídas (a idéia de “distribúido” do EJB é algo diferente, me refiro a infraestruturas físicas diferentes para cada aplicação), e sim como um “super servidor” monolítico ou em cluster, hospedando muitas aplicações diferentes. Isso é o oposto da idéia de microserviços. Imaginemos uma arquitetura baseada em microservices, com uma constelação de aplicações pequenas que fazem coisas específicas, e cada uma rodando em um JEE container “leve”…Me parece como usar um ônibus espacial para dirigir até a praia, quando poderíamos usar um carro. E, claro, poderíamos configurar nosso JEE container “leve” com um, digamos, “web profile”; mas se eu quero apenas um web container, faz sentido usar o Tomcat (ou qualquer outro), ou “desmontar” o Wildfly até só sobrar o Undertown?

    Outra tendência do software moderno são as ferramentas DevOps, baseadas em conteineres que fornecem uma construção simples/rápida de um ambiente para a aplicação. Posso estar enganado, mas isso sempre me traz à mente a idéia de aplicação “leve”, o que é o oposto de qualquer frase que tenha “JEE container” no meio. É possível usar o Docker ou mesmo o Chef ou Puppet, com o Wildfly ou Glassfish? Certamente, não há o que impeça. Mas se queremos um ambiente de execução automatizado para um microserviço especializado que, digamos, apenas expoe um servico REST…um microservice simples. Não seria mais simples apenas simplificar?

    (O JEE tem várias áreas de atrito com esses conceitos; um evangelista da RedHat lançou recentemente um pequeno e muito interessante livro abordando essas questões no ambiente do Java: link e download aqui -> http://developers.redhat.com/promotions/distributed-javaee-architecture/)

    Um último ponto (ufa…) que sempre me vem à mente é uma coisa que foi levantada no post do @alberto.souza: o JEE NÃO SERVE PARA INOVAR. Isso é um fato. Isso é ruim? Na minha opinião, não. Acho as especificações do JEE excelentes, são abrangentes e oferecem padronizações importantes. Mas é isso que elas são: padronizações. Como tal, são limitadas, e fica a cargo das implementações oferecem recursos além do que está especificado. O que vejo como reflexo negativo disso é o fato de que não sabemos o futuro. Estamos aqui falando de frameworks e pode ser que daqui a um ano nenhum deles continue existindo. Quem vai dizer isso é o mercado, e as inovações e as mudanças que a engenharia de software trazem naturalmente. Penso que o Spring e os outros que citei, enquanto frameworks de mercado, podem responder mais rapidamente à essas mudanças, enquanto o foco do JEE é algo mais próximo da estabilidade e padronização, do que a inovação. Isso pode nem ser um problema em alguns contextos. Em outros, certamente o é.

    Se alguém teve paciência para ler até este ponto, eu agradeço. Após todas essas palavras que podem ou não fazer sentido, permitam-me voltar ao ponto inicial: sou contra o modelo de programação baseado no JEE application server. Sempre que possível, vou optar pelo Spring, pelo Play!, pelo Grails, e outros frameworks que oferecem soluções sem depender do ambiente de execução.

    Obrigado.

  20. Gustavo Henke 26/12/2015 at 00:31 #

    Trabalho numa empresa em que temos uma aplicação com mais de 10 anos de código JEE 4, em um JBoss 4.
    Agora, finalmente, vamos iniciar um processo de atualização do servidor (JBoss 6? JBoss 7? Wildfly? não sabemos). A decisão vai estar nas chances de reaproveitamento do código legado.

    Caso precisemos reescrever parte do sistema, assim será. Mas aí também não sabemos o que será usado, se será JEE 7, Spring, Play!, ou qualquer outra coisa.

    Como estarei à frente do projeto, acabei esbarrando neste post para juntar informações sobre a decisão que vou tomar.
    E bônus: ainda tenho muitas dúvidas pois nunca desenvolvi nenhuma aplicação Java “do zero”.

  21. Alberto Souza 28/12/2015 at 12:21 #

    Acho que o objetivo do post foi alcançado :). Temos um lugar com várias opiniões sobre as duas plataformas mais dominantes do mundo Java!

    Gustavo, na minha opinião, um projeto sendo iniciado do zero sempre deve usar o que existe de mais atualizado. Então eu iria de Java EE 7 ou Spring 4.x… Com qualquer um dos dois você vai atingir seu objetivo, como foi colocado no post e principalmente nos comentários, o Spring não exclui o Java EE, então nada impede de você utilizar ele para desenvolver e aproveitar o que for necessário do container Java EE. Esse é um caminho que eu gosto, mesmo que adicione uma complexidade adicional de configurações extras.

  22. Henry 19/01/2016 at 15:03 #

    Excelente post e muito bem escrito, vocês arrebentam no quesito de ensino, meus parabéns!

  23. Marcelo Daniel 19/01/2016 at 15:35 #

    Só uma colocação pro colega Tiago. Acredito que o foco aqui é Java e não ruby ou outras linguagens. Não carece comparar infraestrutura. Um exemplo simples é que se for por este lado nem servlet container entra no meio. Antes de considerar que balanceamento de carga e coisas do gênero não são essenciais considere fazer um deploy de uma aplicação bancária sem isso.
    Existe uma imensa diferença em fazer um software e manter um software.

  24. Marcelo Yukio 20/01/2016 at 10:49 #

    Excelente texto!

    Parabéns Alberto e aos que compartilharam nos comentários.
    Um caminhão do melhor conteúdo sobre o assunto.

    Mesmo entendendo que o Spring tem o objetivo de complementar o Java EE.
    Acredito que não existe uma “batalha”, mas, um espírito de competitividade entre as plataformas.
    E isso é extremamente saudável para o mercado e para nós que utilizamos.
    Nesse sentido, isso faz que elas não se acomodem e então, são “obrigados” a se reinventarem e desenvolverem novas soluções inovadoras.

    Ambas são consolidadas e maduras, claro que tem seus pontos positivos e negativos.
    O uso é questão de gosto…

    Abraço.

  25. Carlos 24/01/2016 at 06:24 #

    Muito bom o texto, eu ainda prefiro Java EE, pq só aprendi a trabalhar com ele hehe, mias estou curioso para conhecer um pouco mais de spring.

  26. Vanderlei 28/01/2016 at 16:56 #

    E quanto ao Deltaspike? Poderia encaixá-lo no JEE….

  27. Emerson Barros 29/11/2016 at 23:36 #

    Cara parabens pelo artigo , me ajudou muito no TCC que estou elaborando pra faculdade , com o tema de o por que usar o Spring, parabens.

  28. Emerson Barros 29/11/2016 at 23:38 #

    Inclusive gostaria de inclui-lo no meu projeto , dando os devidos créditos é claro. Senão for problema!!!

  29. Paulo Silveira 30/11/2016 at 11:39 #

    pode fazer 🙂

  30. RONCAT 16/03/2017 at 13:11 #

    Cara, muito bom! Valeu por postar.

Deixe uma resposta