Trabalhe com Java EE e Spring juntos

Postado em 31. mai, 2012 por Mário Amaral em Java

Existem várias discussões recentes sobre se devemos utilizar o Spring ou o JavaEE em nossos novos projetos, já que muitas das facilidades fornecidas pelo Spring estão agora disponíveis por padrão a partir do JavaEE 6, talvez indo além. A maioria desses posts realiza comparacões entre o Spring e o JavaEE, mostrando pontos fracos e fortes de cada plataforma e determinando um vencedor na disputa. O que esses autores esquecem é que não é necessário escolher entre um ou outro, sendo plenamente possível utilizar tanto bibliotecas do JavaEE e do Spring em conjunto, conseguindo o melhor dos dois mundos, se houver a necessidade.

Logo Spring

Neste post usaremos como exemplo uma aplicação JSF 2.0 rodando em um servlet container simples (como o Tomcat ou o Jetty, por exemplo), usando o Spring para fornecer injeção de dependências e controlar o ciclo de vida dos ManagedBeans do JSF.

O primeiro passo para realizar a integração é registrar o listener do Spring e informar o local do arquivo de configurações no web.xml. Com isso, todos os serviços do Spring já estarão disponíveis no startup da aplicação.

<!-- Listener do Spring -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!-- Local do arquivo de configuração -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/applicationContext.xml</param-value>
  </context-param>

Como iremos delegar para o Spring o controle sobre o ciclo de vida de nossos ManagedBeans, também temos que registrar o listener que nos permitirá utilizar os escopos padrões de uma aplicação web, como request ou session:

  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>

Agora, é só indicar ao JSF para delegar a criação dos ManagedBeans para o Spring, registrando um el-resolver no faces-config.xml:

<faces-config>
	<application>
		<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
	<application>
	...
</faces-config>

A partir desse ponto, podemos usar as anotações do Spring para criar os ManagedBeans. Um bean simples com JSF seria escrito normalmente da seguinte maneira:

@ManagedBean
@RequestScoped
public class ProdutoBean{
    private List produtos;
    public List getProdutos(){
        if(produtos == null){
            ProdutoDAO dao = new ProdutoDAO();
            produtos = dao.listaTodos();
        }
        return produtos;
    }
}

Escrever esse mesmo exemplo usando o spring é muito simples, basta trocar as anotações do JSF pelas (quase) equivalentes do Spring:

@Controller // Equivalente à @ManagedBean
@Scope("request") // Equivalente à @RequestScoped
public class ProdutoBean{

    private List produtos;

    public List getProdutos(){
        if(produtos == null){
            ProdutoDAO dao = new ProdutoDAO();
            produtos = dao.listaTodos();
        }
        return produtos;
    }
}

Para acessar a lista de produtos de uma página, é só referenciar o bean usado a Expression Language:

    <h:dataTable value="#{produtoBean.produtos}" var="produto">

A grande vantagem é que agora podemos receber injeções de dependências diretamente em nossos beans. Vamos injetar o ProdutoDAO. Precisamos indicar para o Spring que o ProdutoDAO é um objeto injetável, faremos isso com a anotação @Repository:

@Repository
public class ProdutoDAO{
...
}

E agora, é só fazer a injeção da dependência no ProdutoBean:

@Controller
@Scope("request")
public class ProdutoBean{
    @Autowired // Anotação do Spring para injeção
    private ProdutoDAO dao;

    private List produtos;

    public List getProdutos(){
        if(produtos == null){
            produtos = dao.listaTodos();
        }
        return produtos;
    }
}

O Spring não é a única solucão para injeção de dependências fora de um servidor de aplicação. Poderiamos utilizar o Weld para nos fornecer injeção padrão JavaEE por meio do CDI, permitindo inclusive customizar a criação dos objetos. O uso do Spring, entretanto, torna mais fácil integrar nosso projeto com outras funcionalidades do framework, como Security, AOP, Transaction, etc., pois o ecossistemas Spring é enorme, bastando apenas configurar e habilitar os serviços no applicationContext.xml.

Sempre podemos considerar a integração com o Spring em nossos sistemas, seja para utilizar algum dos seus serviços que não tem especificação equivalente no JavaEE, seja para substituir alguma especificação cuja implementação do Spring forneça mais funcionalidades, ou simplesmente porque a implementação do Spring é a que a equipe mais domina.

E você, já integrou o Spring e o JavaEE em algum projeto?

Mário Amaral ()

Mais sobre o autor

Tags: , , ,

13 Respostas para “Trabalhe com Java EE e Spring juntos”

  1. Ótimo post! Usar o melhor dos 2 mundos é a solução correta! Uso tanto CDI e Spring. Cada projeto pede uma abordagem. Parabéns!

  2. Vitor

    31. mai, 2012

    Sem contar que, para quem precisa ViewScope no JSF usando Spring, pode tranquilamente implementá-lo. Já fiz isso e funciona 100%.
    Segue link com o exemplo: http://www.esseconhece.com.br/programacao/java/disponibilizando-viewscope-para-spring/

  3. Renato

    31. mai, 2012

    Grande Mario
    Grande post
    Grande tema
    Parabéns pela iniciativa

  4. Allan

    31. mai, 2012

    Olha, para ser sincero, só pelo exemplo citado, não vi grande vantagem em adicionar o Spring ao projeto. (pelo que foi apresentado).

    Na primeira parte, do @ManagedBean, fica igual, só trocam as anotações.

    Na segunda, “se for só pelo cdi”, eu optaria pelo Weld, assim fica transparente quando se a aplicação for para um servidor de aplicação ou, mesmo se não for, você escapa desses montes de xml de configuração do Spring.

    Sei das vantagens do Spring. Mas se for “só pra isso”, não usaria não.

    Abs!!!!

  5. Frederico Maia

    05. jun, 2012

    Neste exemplo realmente não houve vantagem alguma. Pelo contrário o CDI resolve tudo isso muito bem e mais simples ainda se já estiver em um container EE.

    Vitor – No JEE já temos o escopo de ViewScope além de podermos criar escopos customizados.

    Caso haja alguma integração com os serviços do Spring como Security por exemplo, aí sim, concordo que seria vantajoso.

  6. Paulo Silveira

    05. jun, 2012

    oi Frederico

    É mais esse o caso mesmo: onde voce já tenha um sistema dependente de Spring, em especial dos seus milhares de templates/beans/extensões.

  7. Gilmar M. dos Santos

    06. jun, 2012

    Muito bom o post, nunca desenvolvi uma aplicação que o spring gerenciasse o ciclo de vida do jsf, eu sempre criava uma classe de serviço onde o Menaged Bean se comunicava. Agora vou fazer desse jeito.

    Parabéns pelo post!!!!!

  8. Luiz

    06. jun, 2012

    Show de bola!! Excelente Post. É sempre bom saber que temos opções e que essas opções podem se integrar!!

    Abraço

  9. Elizeu Santos

    07. jun, 2012

    Muito bom.
    QUANDO posso optar, costumo utilizar o Spring para IoC e JSF2 para as camadas. Procuro aproveitar o melhor de cada tecnologia.

  10. Rafael Roque

    11. jun, 2012

    Apenas como dica:
    Caso a localização do arquivo seja WEB-INF/applicationContext.xml o context-param não precisa ser informado,o Spring já entende esse caminho como padrão.

    Muito bom texto!

  11. João Henrique

    28. jun, 2012

    Excelente post , simples e claro.(Muito show).

    É muito bom ver artigos práticos e objetivos como esse.

  12. felipe

    05. set, 2012

    Vou fugir do assunto, tenho uma aplicação com spring e meu serv de homologação não tem acesso para fora (web) agora quando eu coloco a aplicação na homologação ela não funciona.
    como eu faço as declarações apontando para endereços locais.
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd

    Desculpa se fuji muito, muito, muito, do assunto em questão

Trackbacks/Pingbacks

  1. 10 razões para migrar sua aplicação para JSF 2 | blog.caelum.com.br - setembro 19, 2012

    [...] A adoção do JavaEE 6 pode ser considerada um sucesso, fato esse pois discussões antigas sobre JavaEE vs Spring voltaram, e antigamente a especificação perdia fácil (quem não se lembra daquela MundoJ – EJB X Spring). Atualmente o Java EE agora uma boa relação com outros frameworks, como o Spring. [...]

Deixar uma Resposta