Você está na página 1de 37

Adendo - Spring Framework (2.

5)
Framework para
Desenvolvimento de Aplicações
em Java

Diego Pacheco

Set/2009

Apostila desenvolvida especialmente para a Crom Microsystems.


Sua cópia ou reprodução é livre.
Sobre o Autor

Diego Pacheco

Técnico em Processamento de Dados e graduando em Ciências da Computação (7º sem.)


na Ulbra. Já trabalhou com desenvolvimento de software em VB, ASP, .NET e PHP.
Atualmente é Arquiteto de Software, certificado pela Sun, atua desenvolvendo soluções
corporativas em arquitetura JEE, provendo coaching/mentoring em software e processo
de desenvolvimento de software. Gosta muito de música, tocar guitarra, jogar PSP,
Bloggar, Ler - principalmente as incríveis histórias do Conan -. Mantem o blog <
http://diego-pacheco.blogspot.com/> a mais de 3 anos.
Spring Framework – Framework para Desenvolvimento de Aplicações Java

Sumário
Sobre o Autor .................................................................................................................................. 3

6. Anotações e Web .............................................................................................................. 1


Objetivos ...................................................................................................................................... 2
Anotações no Java.................................................................................................................. 3
Anotações no Spring Framework .................................................................................... 7
Anotações para injeção ........................................................................................................ 9
Testes Unitários com TestNG ........................................................................................... 14
Integração com JSF ............................................................................................................... 18
Expondo os seus beans via JMX ................................................................................... 29
Espaço para anotações ....................................................................................................... 33

Diego Pacheco – http://diego-pacheco.blogspot.com I


Spring Framework – Framework para Desenvolvimento de Aplicações Java

6. Anotações e Web

Diego Pacheco – http://diego-pacheco.blogspot.com


Spring Framework – Framework para desenvolvimento de aplicações java

Objetivos
• Conhecer os recursos básicos de anotações do Spring Framework;
• Saber construir testes unitários utilizando TestNG com anotações e Spring
Framework.
• Saber como integrar o Spring Framework a uma aplicação Web com JSF.
• Saber como expor um bean do Spring como um JMX.

Diego Pacheco – http://diego-pacheco.blogspot.com 2


Spring Framework – Framework para desenvolvimento de aplicações java

Anotações no Java

Com o lançamento da versão 5 do Java, ganhamos um poderoso recurso, as


anotações. Antes do Java 5 a comunidade já tinha inventado algumas maneiras de
trabalhar com metadados, isto era feito com o Xdoclet e outras soluções similares,
mas a abordagem tinha alguns problemas.

Dentre os diversos problemas, destaco a propenção a erros, pois o recurso nada


mais era do que algumas tags em um bloco de documentação do Javadoc. Além
disso, a documentação ficava misturada com metadados e sempre era necessário
executar uma task ant para realizar a leitura das informações e aplicar o
processamento necessário.

Agora com as anotações é possivel ter estes recursos de forma nativa e com muito
mais beneficios, porque este recurso já vem com o Java e o compilador do Java - o
Javac - verifica sintática e semânticamente a validade das anotações.

Quando trabalhamos com anotações podemos definir em que tempo do programa


vamos utilizar este recurso, os valores possíveis são definidos pela enumeração
java.lang.annotation.RetentionPolicy conforme segue a baixo:

• SOURCE
• CLASS
• RUNTIME
A retenção do tipo SOURCE é descartada pelo compilador, ou seja, só é valida em
tempo de design. A retenção do tipo CLASS é a padrão, o compilador marca na
classe mas a JVM não mantem essa informação acessível em tempo de runtime. Se
você deseja acessar a anotação em tempo de runtime, precisa utilizar a retenção do
tipo RUNTIME e com isso você pode acessar o elemento anotado via reflection.

Além das informação sobre o tipo de retenção das anotações, quando criamos este
tipo de recurso ainda precisamos especificar qual é o alvo da anotação, ou seja, em
que tipo de elemento ela vai estar atuando. Os elementos suportados são definidos
pela enumeração java.lang.annotation.ElementType, que segue abaixo:

• TYPE
• FIELD
• METHOD
• PARAMETER
• CONSTRUCTOR

Diego Pacheco – http://diego-pacheco.blogspot.com 3


Spring Framework – Framework para desenvolvimento de aplicações java

• LOCAL_VARIABLE
• ANNOTATION_TYPE
• PACKAGE

Os recursos mais utilizados em termos de elementos são para interfaces e classes


através do TYPE, para métodos o elemento METHOD e para anotar pacotes o
PACKAGE.
As anotações são úteis para diversos motivos, pois conseguimos definir um modelo
de metaprogramação de forma fácil e verificável. Confira um exemplo de utilização
de anotações abaixo.

package com.blogspot.diegopacheco.springframework25.annotations.java;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Anotação que infica que um campo de uma classe nada pode ser nulo ou vazio. <br>
* Logo você é obrigado a informar um valor ao campo que for anotado com esta anotação.
*
* @author Diego Pacheco
* @version 1.0
* @since 26/09/2009
*
*/

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CampoObrigatorio {

}
Código 6.1 CampoObrigatorio.Java – Anotação do Java 5

O código acima se refere a uma anotação, repare que para criar uma anotação foi
utilizado mais 3 anotaões, duas você já conhece, são referentes a política de
retenção e ao tipo de elemento anotadado.
A anotação @Documented indica que esta anotação possui Javadoc. Repare
também que para criar a anotação foi utilizado o @interface, isto é o que indica que
é uma anotação para o compilador do Java.

Diego Pacheco – http://diego-pacheco.blogspot.com 4


Spring Framework – Framework para desenvolvimento de aplicações java

Agora vamos colocar esta anotação em um objeto, confira o código abaixo:


package com.blogspot.diegopacheco.springframework25.annotations.java;

public class Pessoa {

@CampoObrigatorio
private Integer id;

private String nome;

public Pessoa() { }

public Pessoa(Integer id, String nome) {


super();
this.id = id;
this.nome = nome;
}

public Integer getId() {


return id;
}
public void setId(Integer id) {
this.id = id;
}

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}

@Override
public String toString() {
return "id: " + id + ",Nome: " + nome;
}

}
Código 6.2 Pessoa.Java – Pojo com anotação

Repare que este é um pojo normal com dois atributos, sendo um nome do tipo
String e um id do tipo Integer, além dos construtores vazio e full e seus métodos
getters e setters.

Perceba que o campo id está anotado, a anotação criada acima chamada


@CampoObrigatório, agora vamos ao código que processa a anotação e manipula
as informações da mesma, confira o código abaixo:

Diego Pacheco – http://diego-pacheco.blogspot.com 5


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.annotations.java;

import java.lang.reflect.Field;

public class TestaAnotacaoMain {

public static void main(String[] args) {

Pessoa p = new Pessoa();


p.setNome("Diego Pacheco");

try{
validate(p);
System.out.println("Objeto válido!");
}catch(Exception e){
System.out.println("Objeto inválido!");
e.printStackTrace();
}

@SuppressWarnings("unchecked")
public static void validate(Pessoa p) throws Exception {
Class<Pessoa> clazz = (Class<Pessoa>) p.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(CampoObrigatorio.class))
{
field.setAccessible(true);
if (field.get(p) == null){
throw new RuntimeException("O campo
obrigatório não foi informado. Objeto inválido! ");
}

}
}
}

Código 6.3 TestaAnotacaoMain.Java – Pojo com anotação

No código acima, o objeto Pessoa é instânciado para a memória e apenas a


propriedade nome é informada, perceba que o id não é informado em momento
algum no código a cima.

O método validate processa a validação do objeto Pessoa utilizando a API de


reflecation do Java e é verificado se o campo anotado com a anotação
@CampoObrigatorio tem valor, caso ele seja nulo uma exception é levantada
informando este erro.

Diego Pacheco – http://diego-pacheco.blogspot.com 6


Spring Framework – Framework para desenvolvimento de aplicações java

Anotações no Spring Framework

O Spring é conhecido pela utilização de arquivos xml para configuração de


injeção de dependências (DI) e bem como inversão de controle (IoC), utilizar xml é
bom porque possibilita ao desenvolvedor ter em um único lugar todas as
configurações de injeções do seu sistema, além de ser mais extensivél, porque
podemos modificar o comportamento da aplicação sem abrir o código e sem ter
que recompilar o código.

Porém a utilização de xml tem desvantagens, como por exemplo, ser mais propença
a erros de digitação e de configuração, além de ser menos produtivo do que as
anotações, as anotações dão muito mais produtividade e simplicidade para o
desenvolvedor.

Apartir do Spring Framework 2.5 várias anotações ficaram disponíveis para facilitar o
trabalho e prover um leque de opções maior do que existia nas outras versões da
solução. Esta versão do Spring implementa a JSR-250 que é sobre anotações padrão
do Java como @Resource, @PostConstruct, and @PreDestroy.

Confira o código abaixo:

package com.blogspot.diegopacheco.springframework25.annotations.spring;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Component;

@Component
public class AnotacoesJava {

@PostConstruct
public void init(){
System.out.println("Código de inicialização...");
}

@PreDestroy
public void shutdown(){
System.out.println("Código de shutdown...");
}

}
Código 6.4 AnotacoesJava.Java – Classe que usa anotações padrão

Como você pode reparar a classe acima está utilizado duas anotações padrão do
Java @PostConstruct, and @PreDestroy que serão executadas pelo spring depois de
contruir o objeto e antes de destruir o mesmo.

Diego Pacheco – http://diego-pacheco.blogspot.com 7


Spring Framework – Framework para desenvolvimento de aplicações java

Para ativar este recurso no spring é necessário registrar um bean post processor
padrão, confira esta configuração no código abaixo.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
2.5.xsd">

<context:annotation-config/>
<context:component-scan base-package="com.blogspot.diegopacheco"/>

</beans>
Código 6.5 spring-annotation-beans.xml – XML de configuração

Existem 3 pontos importantes neste xml, o primeiro é a utilização do schema xsd


chamado de context, é através dele que realizamos configurações no contexto do
spring. O segundo ponto é a utilização da entrada annotation-config, isto registra
os bean post processors do spring para tratamento de anotações. Por fim o terceito
ponto é a utilização de component-scan que indica um pacote base, logo o spring
vai varrer todos os subpacotes a procura de outros beans que estejam anotados.

Vamos ver o código para testar a utilização de anotações com o Spring Framework
2.5, confira o código abaixo:
package com.blogspot.diegopacheco.springframework25.annotations.spring;

import org.springframework.context.support.AbstractApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestaAnotacoesJava {


public static void main(String[] args) {

AbstractApplicationContext ctx = new


ClassPathXmlApplicationContext("classpath:spring-annotation*.xml");
ctx.getBean("anotacoesJava");
ctx.registerShutdownHook();

}
}
Código 6.6 TestaAnotacoesJava – Classe para testes

Neste código foi instânciado o contexto do spring e obtido o bean anotado e


depois o contexto foi derrubado com o registerShutdownHook().

Diego Pacheco – http://diego-pacheco.blogspot.com 8


Spring Framework – Framework para desenvolvimento de aplicações java

O Spring vai procurar beans com as seguintes anotações

• @Component

• @Service

• @Repository

• @Controller

Caso ele encontre algum bean com alguma destas anotações, ele vai registrar o
bean no contexto, o nome do bean vai ser definido da seguinte forma: Supondo
que a classe se chama PessoaFisicaService o bean ter o mesmo nome só que com a
primeira letra não captalizada, ou seja: pessoaFisicaService.

A anotação @Component é a mais genérica do Spring, ela serve para indicar que é
um bean gerenciado pelo Spring, você utiliza isso em qualquer bean de propósito
geral.

As outras anotações são mais específicas, elas indicam um serviço @Service, um


objeto de controle (arquitetura MVC) @Controller e um objeto de acesso a dados,
vulgo DAO com @Repository.

Quando você utiliza @Service, @Component ou @Controller ainda não tem uma
diferença prática, mas o spring pretende utilizar isso como informações para
aspéctos em futuras implementações.

Quanto a anotação @Repository, você já ganha o recurso de tradução de


exceptions automaticamente, logo, não vai ter que lidar com exceptions específicas
como as de lock otimista do JPA.

Anotações para injeção


O Spring também prove anotações para injeção de beans. Para isso estão
disponíveis as anotações:

• @Resource

• @Autowired

A anotação @Resource faz a injeção baseado nos nomes dos beans e a anotação
@Autowired faz baseada em tipos. Se você não trabalha com interfaces ou tem só
uma implementação, pode usar @Autowired sem problemas, mas a sua aplicação
pode crescer e com isso podem vir vários erros de injeção.

Para resolver este problema precisamos qualificar a injeção utilizando a anotação


@Qualifier indicando o identificador do bean que você quer.

Diego Pacheco – http://diego-pacheco.blogspot.com 9


Spring Framework – Framework para desenvolvimento de aplicações java

Confira o código abaixo para ver a utilização destas anotações em prática.


package com.blogspot.diegopacheco.springframework25.annotations.spring;

import org.springframework.stereotype.Component;

@Component
public class Livro {

private String isbn;


private String titulo;

public Livro() {
isbn = "10ergregKL2";
titulo = "O código de Da vince";
}

public String getIsbn() {


return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}

public String getTitulo() {


return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}

@Override
public String toString() {
return "[livro={isbn: " + isbn + ",titulo: " + titulo + "}]";
}

}
Código 6.7 Livro.java – Pojo Livro

Este é um pojo simples, que foi anotado com a anotação @Component do spring
framework 2.5, agora vamos ao bean autor, neste bean vamos injetar o código do
livro que está acima.
package com.blogspot.diegopacheco.springframework25.annotations.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component()
public class Autor {

private Integer id;


private String nome;

@Autowired
private Livro livro;

public Autor() {

Diego Pacheco – http://diego-pacheco.blogspot.com 10


Spring Framework – Framework para desenvolvimento de aplicações java

id=0;
nome="Sem nome";
}

public Integer getId() {


return id;
}
public void setId(Integer id) {
this.id = id;
}

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}

public Livro getLivro() {


return livro;
}
public void setLivro(Livro livro) {
this.livro = livro;
}

@Override
public String toString() {
return "id: " + id + ",Nome: " + nome + ", Livro: " + livro;
}

Código 6.8 Autor.java – Pojo Livro

Como você pode perceber, foi utilziado a anotação @Autowired, para realizar a
injeção, neste caso também poderíamos utilizar a anotação @Resource. Vamos ao
código que sobe o contexto do Spring e por fim ao teste desta aplicação.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
2.5.xsd">

<context:annotation-config/>
<context:component-scan base-package="com.blogspot.diegopacheco"/>

</beans>

Código 6.9 spring-annotation-beans.xml xml de configuração

Diego Pacheco – http://diego-pacheco.blogspot.com 11


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.annotations.spring;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestaInjecaoAnotacoes {


public static void main(String[] args) {
ApplicationContext ac = new
ClassPathXmlApplicationContext("classpath:spring-annotation*.xml");
Autor a =(Autor)ac.getBean("autor");
System.out.println(a);
}
}
Código 6.10 TestaInjecaoAnotacoes.java – Clase de testes

Você já deve ter reparado que esta abordagem tem todas as vantagens que
descrevi no início deste capítulo, mas ainda tem mais uma desvantagem, nós não
conseguimos definir vários beans com a mesma classe e com dados diferentes,
neste sentido a abordagem de xml é mais vantajosa.

Nós poderiamos deixar alguma injeção obrigatória e caso você não faça isso o
spring irá levantar uma exception. Para isso vamos utilizar a anotação @Required,
confira o código abaixo modificado do exemplo anterior.
package com.blogspot.diegopacheco.springframework25.annotations.spring;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Component;

@Component
public class Livro {

private String isbn;


private String titulo;

public Livro() {
isbn = "10ergregKL2";
titulo = "O código de Da vince";
}

public String getIsbn() {


return isbn;
}

@Required
public void setIsbn(String isbn) {
this.isbn = isbn;
}

public String getTitulo() {


return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;

Diego Pacheco – http://diego-pacheco.blogspot.com 12


Spring Framework – Framework para desenvolvimento de aplicações java

@Override
public String toString() {
return "[livro={isbn: " + isbn + ",titulo: " + titulo + "}]";
}

Código 6.11 Livro.java – Anotado

Perceba que a classe livro agora tem a anotação @Required no setter da


propriedade ISBN, logo, se você não injetar um valor, o spring vai levantar uma
exception e o contexto não irá subir.

O spring permite mesclarar informações de anotações com XML, confira a


configuração abaixo para injeção deste atributo obrigatório.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
2.5.xsd">

<context:annotation-config/>
<context:component-scan base-package="com.blogspot.diegopacheco"/>

<bean id="livro"

class="com.blogspot.diegopacheco.springframework25.annotations.spring.Liv
ro"
>
<property name="isbn" value="1000ISBN12" />
</bean>

</beans>
Código 6.12 spring-annotation-beans.xml xml de configuração

Diego Pacheco – http://diego-pacheco.blogspot.com 13


Spring Framework – Framework para desenvolvimento de aplicações java

Testes Unitários com TestNG

Nos capitulos anteriores você aprendeu a integrar o Spring Framework com o


Junit, bem como utilizar as suas facilidades para testes unitários. Neste capítulo
você vai ver como utilizar o TestNG através de anotações tanto do TestNG como do
próprio Spring Framework.

Desenvolver aplicações utilizando os bons modelos de design como programação


para interfaces, baixo acoplamento e alta coesão, extensibilidade, di, ioc, através do
Spring framework nos trazem um benefício muito importante, um código que é
testável.

O Spring prove injeção para testes de forma diferenciada da injeção para a sua
aplicação utiliza este recurso. Vamos ver como utilizar alguns recursos de testes
unitários do Spring com anotações, confira o código abaixo:

package com.blogspot.diegopacheco.springframework25.testng;

public interface Calculadora {


public void dividir(Double va, Double vb, ResultadoCallback
callback);
}

Código 6.13 Calculadora.java – Interface de Contrato da Calculadora


package com.blogspot.diegopacheco.springframework25.testng;

public interface ResultadoCallback {


public void processar(Double resultado);
}

Código 6.14 ResultadoCallback.java – Interface de Callback

Diego Pacheco – http://diego-pacheco.blogspot.com 14


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.testng;

import org.springframework.stereotype.Service;

@Service
public class CalculadoraAsync implements Calculadora {

@Override
public void dividir(final Double va, final Double vb,
final
ResultadoCallback callback) {
new Runnable(){
public void run() {
callback.processar(va/vb);
}
}.run();
}
}

Código 6.15 ResultadoCallback.java – Interface de Callback

A classe acima implementa a interface de calculadora de modo assíncrono, ela


processa a divisão em outra thread. Quando o calculo é finalizado quem infocou o
serviço é notificado via um callback.

Vamos ver como testar este código integrando o Spring ao TestNG, para isso
confira a classe abaixo de testes.
package com.blogspot.diegopacheco.springframework25.testng;

import org.springframework.stereotype.Service;

@Service
public class CalculadoraAsync implements Calculadora {

@Override
public void dividir(final Double va, final Double vb,
final
ResultadoCallback callback) {
new Runnable(){
public void run() {
callback.processar(va/vb);
}
}.run();
}
}

Código 6.16 ResultadoCallback.java – Interface de Callback

Diego Pacheco – http://diego-pacheco.blogspot.com 15


Spring Framework – Framework para desenvolvimento de aplicações java

Agora que já temos o que testar vamos criar um teste unitário com o TestNG,
confira o código de testes abaixo:
package com.blogspot.diegopacheco.springframework25.testng;

import junit.framework.Assert;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import
org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;

@Test(groups={"curso-spring"})
@ContextConfiguration(locations={"/spring-test-beans.xml"})
public class CalculadoraTest extends AbstractTestNGSpringContextTests {

private Calculadora calc;

@Test
public void testInjecaoSpring(){
Assert.assertNotNull("A calculadora não foi injetada.",calc);
}

@Autowired
@Test(enabled=false)
public void setCalc(Calculadora calc) {
this.calc = calc;
}

Código 6.17 ResultadoCallback.java – Interface de Callback

Neste código precisamos focar nos seguintes pontos:

• Extensão da classe AbstractTestNGSpringContextTests: Esta é a classe


abstrata do Spring que prove integração e facilidades para trabalhar com o
testNG.

• @Test: Indica que a classe é testável via TestNG e que a classe pertence ao
grupo de testes chamado curso-spring.

• @Test no método testInjecaoSpring indica que o método deve ser testado.

• @Autowired e @Test(enable=false): Indica que o Spring deve injetar a


instância do bean calculadora, como estamos indo por tipo ele vai injetar a
calculadora assíncrona chamada CalculadoraAsync.

• Assert.assertNotNull neste ponto estamos utilizando asserções para testar


se o código está fazendo o que deveria, caso isso não seja válido, uma
exception será levantada com a mensagem passada no primeiro argumento
do método.

Diego Pacheco – http://diego-pacheco.blogspot.com 16


Spring Framework – Framework para desenvolvimento de aplicações java

• @ContextConfiguration serve para indicar ao spring onde estão os xmls de


configuração para o contexto de testes que ele irá montar.

Agora vamos ver outros recursos do Spring com o TestNG, podemos utilizar
diversas anotações que nos provem diversas facilidades como:

• @Timed: Especifica um tempo em milisegundos para o método executar,


caso demore mais do que o tempo especificado uma exception é levantada e
o teste irá falhar.

• @Rollback: Especifica se o método irá dar um rollback na transação ou se


será permitido que a transação efetue um commit no banco de dados.

• @ExpectedException: Especifica que uma exception do tipo especificado


deve ser levantada, este recurso é ideal para testar cenários de erros.

• @IfProfileValue: Este recurso permite a execução do método de testes


apartir de um profile condicional. Este profile é definido por uma variavél de
ambiente e um valor, caso a váriavel do sistema tenha o valor que você
informou o método será executado.

Diego Pacheco – http://diego-pacheco.blogspot.com 17


Spring Framework – Framework para desenvolvimento de aplicações java

Integração com JSF

Java Server Faces vem se tornando muito popular no desenvolvimento de aplicações Web
com Java pela quantidade componentes prontos de riqueza visual dos seus componentes.
O Spring Framework 2.5 possui integração com o Java Server Faces 2.5, vamos ver como
configurar esta integração em uma aplicação Web utilizando o padrão MVC.

Figura 6.1 – Padrão MVC

O JSF é uma das implementações de um framework MVC, o propósito de um framework


MVC é separar a camada de apresentação(view) da camada de negócio(model), é comun
utilizar na parte do model EJB ou Spring Framework, o JSF se encarrega das camadas de
view e controller.

Este padrão é largamente utilizado em desenvolvimento de aplicação Web com Java, JSF é
uma das implementações, mas existem outras como o Strus, Webwork, Stripes, etc.

Para integrar o Contexto do Spring ao JSF é necessário registrar o listener do Spring no


web.xml para que o contexto do Spring suba automaticamente quando a aplicação inicia e
bem como registrar o org.springframework.web.jsf.el.SpringBeanFacesELResolver como
ElResolver do JSF. Depois disso você pode utilizar o Spring com o JSF normalmente.

Então vamos ver essas configurações na prática e bem como uma aplicação com todas as
camadas típicas da arquitetura MVC usando Spring Framework, JSF, Jboss RichFaces e
Annotations.

Diego Pacheco – http://diego-pacheco.blogspot.com 18


Spring Framework – Framework para desenvolvimento de aplicações java

<?xml version="1.0" encoding="UTF-8"?>


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

<!-- Configurações da Aplicação -->


<display-name>Adendo-Curso-Spring-JSF</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>30</session-timeout>
</session-config>

<!-- Configurações do Spring Framework -->


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-beans-core.xml</param-value>
</context-param>

<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener-
class>
</listener>
<listener>
<listener-class>

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

<!-- Configurações para utilização de JSF -->


<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config-beans.xml,/WEB-INF/faces-
config-nav.xml</param-value>
</context-param>

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-
class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>

<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsp</param-value>

Diego Pacheco – http://diego-pacheco.blogspot.com 19


Spring Framework – Framework para desenvolvimento de aplicações java

</context-param>

<listener>
<listener-
class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>

<!-- Configurações do JBoss Richfaces -->


<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>laguna</param-value>
</context-param>

</web-app>

Código 6.18 web.xml – Configurações da Aplicação

Como você pode perceber, as configurações de Spring, JSF e Jboss RichFaces estão
separadas por comentários, vamos ver o significado de cada configuração uma a uma,
começando com as configurações do Spring Framework.

O parametro para Servlets chamado contextConfigLocation serve para indicar aonde estão
as configurações em xml do spring para serem utilizadas na startup do contexto. Na
sequencia o listener do spring chamado
org.springframework.web.context.ContextLoaderListener é responsável por subir o
contexto do spring nesta aplicação web.

Diego Pacheco – http://diego-pacheco.blogspot.com 20


Spring Framework – Framework para desenvolvimento de aplicações java

Por fim é utilizado o org.springframework.web.context.request.RequestContextListener para


trabalhar a tecnologia de MVC do spring com JSF, no nosso caso vamos utiliza-lo apenas
para ver o que está trafegando nos cabeçalhos do http.

Depois vem as configurações do JSF e do Jboss RichFaces que são padrão o único ponto
mais importante a prestar atenção aqui é o parâmetro de servlet chamado
javax.faces.CONFIG_FILES que serve para informar onde estão os arquivos de configuração
do JSF.

No final do arquivo estamos registrando o filter do Jboss Richfaces, bem como a utilização
de um Skin plugável chamado laguna. Vamos ver as configurações do JSF agora, ou seja, os
faces-config.

<?xml version="1.0" encoding="UTF-8"?>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">

<navigation-rule>
<navigation-case>
<from-outcome>sucesso</from-outcome>
<to-view-id>/Pages/lista-cao-pego.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>

</faces-config>

Código 6.19 faces-config-nav.xml– Arquivo com Regras de Navegação

Neste arquivo estão as configurações de navegação dos beans. Vamos ver o arquivo de
configuração dos managed beans e do spring com o ElResolver.

<?xml version="1.0" encoding="UTF-8"?>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">

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

<managed-bean>
<managed-bean-name>carrocinhaBean</managed-bean-name>

Diego Pacheco – http://diego-pacheco.blogspot.com 21


Spring Framework – Framework para desenvolvimento de aplicações java

<managed-bean-
class>com.blogspot.diegopacheco.springframework25.jsf.mb.CarrocinhaBean</
managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>carrocinhaService</property-name>
<property-
class>com.blogspot.diegopacheco.springframework25.jsf.service.CarrocinhaS
ervice</property-class>
<value>#{caveiraoService}</value>
</managed-property>
</managed-bean>

</faces-config>

Código 6.20 faces-config-beans.xml– Arquivo com os MB do JSF

O ponto mais importante deste arquivo é a configuração do SpringBeanFacesElResolver,


depois está sendo declarado o carrocinhaBean que é o controller desta aplicação. Vamos
ver as classes da aplicação neste momento então.

package com.blogspot.diegopacheco.springframework25.jsf.pojo;

import java.io.Serializable;

public class Cachorro implements Serializable {

private static final long serialVersionUID = 1L;

private Integer id;


private String nome;
private String raca;

public Cachorro() { }

public Integer getId() {


return id;
}
public void setId(Integer id) {
this.id = id;
}

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}

public String getRaca() {


return raca;
}
public void setRaca(String raca) {
this.raca = raca;
}

@Override

Diego Pacheco – http://diego-pacheco.blogspot.com 22


Spring Framework – Framework para desenvolvimento de aplicações java

public String toString() {


return "id: " + id + ",Nome: " + nome + ", Raça: " + raca;
}

Código 6.21 Cachorro.java– Pojo que representa um Cachorro

Este é um simples pojo com métodos getters e setters com o construtor vazio e que
implementa Serializable. Vamos ao componente responsável por persistir o objeto.

package com.blogspot.diegopacheco.springframework25.jsf.dao;

import java.io.Serializable;

import org.springframework.stereotype.Repository;

import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro;

@Repository(value="carrocinhaDao")
public class CarrocinhaDao {

public Serializable capturar(Cachorro c){


System.out.println("Cachorro: " + c + " persistido com
sucesso ");
return c;
}

}
Código 6.22 CarrocinhaDao.java– Repository de Carrocinha

Este repositório é resposável por acessar os dados referente ao serviço de carrocinha,


também é conhecido como o pattern DAO. Este código não acessa o banco de dados, mas
você poderia utilizar JPA ou Hibernate sem problema nenhum.

package com.blogspot.diegopacheco.springframework25.jsf.service;

import java.io.Serializable;

import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro;

public interface CarrocinhaService {


public Serializable catar(Cachorro c);
}
}
Código 6.23 CarrocinhaService.java– Serviço de Carrocinha

Esta é a interface de contrato do serviço de carrocinha, os cachorros devem ter cuidado


agora, senão, vão se dar mal. Vamos ver uma implementação deste serviço:

Diego Pacheco – http://diego-pacheco.blogspot.com 23


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.jsf.service;

import java.io.Serializable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import
com.blogspot.diegopacheco.springframework25.jsf.dao.CarrocinhaDao;
import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro;

@Service(value="caveiraoService")
public class CaveiraoCarrocinhaServiceImpl implements
CarrocinhaService {

@Autowired
private CarrocinhaDao dao;

public Serializable catar(Cachorro c) {


Serializable ser = dao.capturar(c);
System.out.println("Cão: "+ ser + " não tem vez!");
return ser;
}

public void setDao(CarrocinhaDao dao) {


this.dao = dao;
}
}

Código 6.24 CaveiraoCarrocinhaServiceImpl– Serviço de Carrocinha Impl

Este é o serviço implementado para carrocinha. Como você pode perceber, ele está
utilizando um dao que é injetado via anotação @Autowired. Este serviço retorna a instância do
Cachorro que foi capturado.

package com.blogspot.diegopacheco.springframework25.jsf.mb;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;

import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro;
import
com.blogspot.diegopacheco.springframework25.jsf.service.CarrocinhaService
;

@Controller(value="carrocinhaBean")
public class CarrocinhaBean {

private Integer id;


private String nome;
private String raca;
private String resultado;

@Resource
private CarrocinhaService carrocinhaService;

Diego Pacheco – http://diego-pacheco.blogspot.com 24


Spring Framework – Framework para desenvolvimento de aplicações java

public CarrocinhaBean() {}

public Integer getId() {


return id;
}
public void setId(Integer id) {
this.id = id;
}

public String getNome() {


return nome;
}
public void setNome(String nome) {
this.nome = nome;
}

public String getRaca() {


return raca;
}
public void setRaca(String raca) {
this.raca = raca;
}

public String getResultado() {


return resultado;
}
public void setResultado(String resultado) {
this.resultado = resultado;
}

public CarrocinhaService getCarrocinhaService() {


return carrocinhaService;
}
public void setCarrocinhaService(CarrocinhaService
carrocinhaService) {
this.carrocinhaService = carrocinhaService;
}

public String catar(){


Cachorro c = new Cachorro();
c.setId(1);
c.setNome(nome);
c.setRaca(raca);

Cachorro caoCatadado = (Cachorro)carrocinhaService.catar(c);


resultado = "Cão: " + caoCatadado.getNome() + " - Catado! ";
return "sucesso";
}

Código 6.25 CarrocinhaBean– Controller da Aplicação

Esta classe é um controller, você pode reparar que ela tem as mesmas propriedades que o
pojo Cachorro tem, isto serve para separarmos objetos que trafegam na tela com os
objetos que trafegam nos serviços e nas regras de negócio.

Diego Pacheco – http://diego-pacheco.blogspot.com 25


Spring Framework – Framework para desenvolvimento de aplicações java

Uma instância de CarrocinhaService é injetada via a anotação @Resource e o método catar


tem a resposabilidade de criar o pojo Cachorro e invocar o serviço de Carrocinha e repassar
o resultado, caso dê tudo certo, o resultado é “sucesso” que irá cair nas regras de
navegação do JSF e levar a execução a outra página.Vamos ver o código das páginas desta
aplicação;

<%@ page contentType="text/html; charset=Cp1252"%>


<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Cp1252" />
<title></title>
</head>
<body>
<f:view>
<h:form>
<rich:panel>
<h:panelGrid>
<h:outputLabel value="Capturar um Cão sem
Sorte" />
<h:panelGroup>
<h:outputLabel id="nome" value="Nome do
Cão:" />
<h:inputText id="nomeTxt"
value="#{carrocinhaBean.nome}" />
</h:panelGroup>
<h:panelGroup>
<h:outputLabel id="raca" value="Raça do
Cão :" />
<h:inputText id="racaTxt"
value="#{carrocinhaBean.raca}" />
</h:panelGroup>
<h:panelGroup>
<a4j:commandButton value="Catar o Cão
agora!" action="#{carrocinhaBean.catar}" />
</h:panelGroup>
</h:panelGrid>
</rich:panel>
</h:form>
</f:view>
</body>
</html>
Código 6.26 main.jsp– Página de captura de cães

Diego Pacheco – http://diego-pacheco.blogspot.com 26


Spring Framework – Framework para desenvolvimento de aplicações java

<%@ page contentType="text/html; charset=Cp1252"%>


<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Cp1252" />
<title></title>
</head>
<body>
<f:view>
<h:form>
<rich:panel>
<h:panelGrid>
<h:outputLabel value="Cão que se deu mal" />
<h:panelGroup>
<h:outputLabel id="result" value="Cão
Capturado:" />
<h:outputLabel id="resuktValue"
value="#{carrocinhaBean.resultado}" />
</h:panelGroup>
</h:panelGrid>
</rich:panel>
</h:form>
</f:view>
</body>
</html>

Código 6.27 lista-cao-pego.jsp.jsp– Página que mostra o cão pego

Diego Pacheco – http://diego-pacheco.blogspot.com 27


Spring Framework – Framework para desenvolvimento de aplicações java

Ao rodar esta aplicação você irá precisar das seguintes dependências em termos de jars:

Figura 6.2 Dependências de Jars

A versão do Spring Framework utilizada foi a versão 2.5.6.SCE e a aplicação roda no Jetty
6.1.3, você pode obter a aplicação completa nos fontes que acompanham apostila.

Diego Pacheco – http://diego-pacheco.blogspot.com 28


Spring Framework – Framework para desenvolvimento de aplicações java

Expondo os seus beans via JMX

JMX é uma solução Java para monitoramento e parametrização do


comportamento da aplicações Java em tempo de runtime. Esta solução é
muito utilizada para o gerenciamento de aplicações Java. Para utilizar este
recurso você não precisar implementar e nem estender nenhum recurso do
Spring Framework. Vamos a um exemplo prático.

package com.blogspot.diegopacheco.springframework25.jmx;

public interface DateService {


public String getDate();
}

Figura 6.28 DateService.java contrato do serviço de dadas

Como você pode perceber esta é um interface como outa qualquer, sem
nada de mais, apenas existe um método chamado getDate que deve
retornar uma String. Vamos ver a sua implementação.

package com.blogspot.diegopacheco.springframework25.jmx;

import java.util.Date;

public class DateServiceImpl implements DateService{


public String getDate() {
return new Date().toString();
}
}
Figura 6.29 DateServiceImpl.java – Serviço de Datas

A implementação é bem simples, apenas retorna o método toString() de um


objeto Date recente, que irá ter a data e hora atual do sistema.

Vamos registrar este bean como um bean do Spring, utilizando xml como de
costume.

Diego Pacheco – http://diego-pacheco.blogspot.com 29


Spring Framework – Framework para desenvolvimento de aplicações java

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-
context-2.5.xsd">

<bean id="dateService"
class="com.blogspot.diegopacheco.springframework25.jmx.DateServiceImpl"

/>

</beans>

Figura 6.30 DateServiceImpl.java – Serviço de Datas

Declaração do bean no contexto do Spring como de costume é feito e sem


nada de novo, agora é possível apenas expor este bean via JMX, sem
esforço de programação, basta utilizar a configuração a baixo.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
2.5.xsd">

<context:annotation-config />
<context:component-scan base-package="com.blogspot" />

<bean id="dateService"

class="com.blogspot.diegopacheco.springframework25.jmx.DateServiceI
mpl" />

<bean id="exporter"
class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=DateService" value-
ref="dateService" />
</map>
</property>
</bean>

</beans>
Figura 6.30 DateServiceImpl.java – Serviço de Datas

Diego Pacheco – http://diego-pacheco.blogspot.com 30


Spring Framework – Framework para desenvolvimento de aplicações java

O Código acima utiliza o recurso do spring chamado de


org.springframework.jmx.export.MbeanExporter que é resposável por expor
os beans via JMX, ele recebe um map com os beans que vão ser expostos,
logo é possível expor mais de um bean.

Existem outras estratégias para exposição de beans com JMX, esta é a mais
simples, caso queira saber mais, consulte a documentação oficial do spring
framework.

Você pode acessar este MBean via um utilitário que vem junto com o JDK do
java o Jconsole, você achar o utilitário na pasta bin do seu JDK, para utilizar
o JMX é comun ter que habilitar este recurso no seu container, cada
container tem uma configuração diferente, recomendo verificar a
documentação do container que você esteja utilizando para maiores
detalhes.

Diego Pacheco – http://diego-pacheco.blogspot.com 31


Spring Framework – Framework para desenvolvimento de aplicações java

Exercícios

1) Crie um beans Pessoa, AnimalDeEstimacao e Casa e injete um no outro usando as


anotaçõess do Spring. Você deve criar o método verifica animais, que deve retornar
um Map contendo o nome do animal e o tipo dele, exe.: mamífero, réptil, etc...
2) Adicione a anotação de ciclo de vida @PostConstruct e @PreDestroy no bean de
Pessoa e faça log do início e fim da aplicação.
3) Exponha o bean pessoa com o método listarAnimais() que deve retornar uma
Sring com todos os animais da pessoa separados por “ ; ”
4) Crie um teste unitário com TestNG para validar se o objeto através do método
verifica animais está correto.
5) Crie uma aplicação web com JSF que você possa cadastrar um animal preferido a
pessoa e depois tenha uma página que mostre o animal cadastrado, não é
necessário acessar banco de dados.

Diego Pacheco – http://diego-pacheco.blogspot.com 32


Spring Framework – Framework para desenvolvimento de aplicações java

Espaço para anotações

Diego Pacheco – http://diego-pacheco.blogspot.com 33