Você está na página 1de 168

Spring Framework (2.

0)
Framework para
Desenvolvimento de Aplicaes
em Java





Diego Pacheco
Dez/2007



Apostila desenvolvida especialmente para a Crom Microsystems.
Sua cpia ou reproduo livre.


Sobre o Autor

Diego Pacheco
Tcnico em Processamento de Dados e graduando em Cincias da Computao(7 sem.)
na Ulbra. J trabalhou com desenvolvimento de software em VB, ASP, .NET e PHP.
Atualmente Arquiteto de Software, certificado pela Sun, atuo desenvolvendo solues
corporativas em arquitetura JEE, provendo coaching/mentoring em software e processo
de desenvolvimento de software. Gosto muito de msica, tocar guitarra, jogar PSP,
Bloggar, Ler e principalmente as incrveis histrias do Conan. Mantenho o blog <
http://diego-pacheco.blogspot.com/> a mais de 3 anos.

Spring Framework Framework para Desenvolvimento de Aplicaes Java

Diego Pacheco http://diego-pacheco.blogspot.com I
Sumrio
1. Introduo .................................................................................................................... 1-1
Objetivos ................................................................................................................................... 1-2
Conceitos Bsicos ................................................................................................................. 1-3
Cenrios de uso .................................................................................................................... 1-7
Portiflio ............................................................................................................................... 1-10
Download .............................................................................................................................. 1-12
Estrutura de Diretrios .................................................................................................. 1-13
Exerccios .............................................................................................................................. 1-15
Espao para anotaes .................................................................................................... 1-16
2. Container IoC .............................................................................................................. 2-1
Objetivos ................................................................................................................................... 2-2
IoC Inversion of control ............................................................................................... 2-3
Registrando Beans ............................................................................................................. 2-13
Singletons e lazy Initialization ................................................................................. 2-15
Lazy Initialization ........................................................................................................... 2-18
Scopos dos Beans ................................................................................................................ 2-20
Criando seu prprio scope ............................................................................................ 2-23
Injeo via setter ................................................................................................................. 2-27
Injeo via construtor ...................................................................................................... 2-29
Injeo de colees ............................................................................................................. 2-31
Injeo entre beans colaboradores ............................................................................ 2-36
Instanciando o contexto Web ....................................................................................... 2-40
Exerccios .............................................................................................................................. 2-42
Espao para anotaes .................................................................................................... 2-43
3. Manipulao de Beans .......................................................................................... 3-1
Objetivos ................................................................................................................................... 3-2
Resource Loaders ................................................................................................................. 3-3
Init-Metohd e InitializingBean ................................................................................... 3-4
Herana de Definies ...................................................................................................... 3-7
Validao .............................................................................................................................. 3-10
Bean Wrapper...................................................................................................................... 3-13
BeanPostProcessors ............................................................................................................ 3-17
Spring Framework Framework para desenvolvimento de aplicaes Java
Diego Pacheco http://diego-pacheco.blogspot.com II
BeanFactoryPostProcessors ............................................................................................ 3-21
Property Editors ................................................................................................................. 3-25
Eventos .................................................................................................................................... 3-30
PropertyPlaceholderConfigurer ................................................................................. 3-33
SingletonBeanFactoryLocator ...................................................................................... 3-36
Internacionalizao ......................................................................................................... 3-40
Exercicios .............................................................................................................................. 3-44
Espao para anotaes .................................................................................................... 3-45
Spring Framework Framework para desenvolvimento de aplicaes Java
Diego Pacheco http://diego-pacheco.blogspot.com III
4. Persistncia .................................................................................................................. 4-1
Objetivos ................................................................................................................................... 4-2
Hierarquia de Exceptions ............................................................................................... 4-3
Acesso a dados usando JDBC ........................................................................................ 4-5
Trabalhando com DataSources .................................................................................... 4-5
Trabalhando com JDBCTemplate .............................................................................. 4-7
Session Factory Bean ........................................................................................................ 4-11
Hibernate Template .......................................................................................................... 4-13
Transaes Declarativas ................................................................................................. 4-18
Exerccios .............................................................................................................................. 4-22
Espao para anotaes .................................................................................................... 4-23
5. Facilitadores ................................................................................................................ 5-1
Objetivos ................................................................................................................................... 5-2
Envio de E-mails ................................................................................................................ 5-3
Agendamento de tarefas com JDK Task ................................................................. 5-10
@Aspect Support ................................................................................................................. 5-16
Testing Support ................................................................................................................... 5-23
AbstractDependencyInjectionSpringContextTests .............................................. 5-24
AbstractAnnotationAwareTransactionalTests ..................................................... 5-27
AbstractTransactionalDataSourceSpringContextTests ..................................... 5-28
Remoting com RMI ........................................................................................................... 5-29
Exerccios .............................................................................................................................. 5-34
Espao para anotaes .................................................................................................... 5-35


Spring Framework Framework para Desenvolvimento de Aplicaes Java

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


I
I
n
n
t
t
r
r
o
o
d
d
u
u

o
o

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-2
Objetivos
Conhecer os conceitos bsicos;
Conhecer os principais cenrios de uso;
Prover uma viso de todo o portiflio do Spring;
Saber onde baixar o Spring;
Conhecer a estrutura de diretrios dos fontes.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-3
Conceitos Bsicos

Spring framework, garanto a voc que no nenhum produto de limpeza,
at pode parecer pelo nome, mas no . Spring um dos frameworks lderes do
mercado full-stack Java/JEE. Esse framework mantido pela empresa Interface21
que tem como presidente, Rod Johnson, o criador do Spring que simplesmente
uma das maiores autoridades em Java. Spring prove diversos benefcios para muitos
projetos, aumentando a produtividade de desenvolvimento e a performance em
tempo de runtime em quanto ao mesmo tempo prove uma cobertura para testes e
muita qualidade para a aplicao.
O Spring prove solues light-weight para construes de aplicaes
corporativas. Enquanto ainda suporta e prove a possibilidade de se usar: transaes
declarativas, acesso remoto atravs de RMI ou Web Services e muitas opes para
persistncia de dados.
O Spring prove tambm uma soluo completa MVC Framework e maneiras
transparentes e elegantes para integrao de AOP ao seu software. Esse framework
extremamente modular, assim voc pode usar somente as partes que lhe
interessam. possvel usar IoC com Struts ou por exemplo, voc pode optar por
usar somente a camada de integrao com Hibernate ou a camada de abstrao
para JDBC. Desenhado para no ser intrusivo, utilizando apenas ele mesmo ou o
mnimo de dependncias para suas funcionalidades.
Esse framework foi muito bem dividido, e isso pode ser observado com
clareza na figura a baixo.
Spring Framework Framework para desenvolvimento de aplicaes java

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



Figura 1.1 Viso Geral

Utilizando o Spring voc j ter um ganho excelente em qualidade de
software em termos de design patterns, utilizando ele praticamente anula o uso de
patterns como Factory e ServiceLocator. Todo Objeto componente de sua aplicao
por default para o Spring um singleton, assim favorecendo as boas prticas e a
performance.
A Empresa Interface21 e com certeza o Spring tem como misso os seguintes
valores:
J2EE Deveria ser muito fcil de usar
melhor programar para interfaces do que para classes, Spring reduz o custo
e a complexidade de usar interfaces para zero.
JavaBeans oferece uma maneira excelente para configurar uma aplicao.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-5
O Design OO mais importante do que qualquer tecnologia de
implementao como, por exemplo, J2EE.
Exception checadas so mal utilizadas no Java. Um framework no deveria
forar voc a capturar exceptions que voc no est apto a se recuperar.
Testabilidade essencial, o Spring ajuda voc a testar seu cdigo mais
facilmente.

O Spring precisa ser prazeroso para quem desenvolve usando ele.
O Cdigo de sua aplicao deveria no depender da API do Spring.
O Spring no compete com as boas solues existentes, mas prove
integrao dessas tecnologias, como exemplo o Hibernate, o Spring no
pretende desenvolver outra, apenas integr-la e prover facilidades.
Algumas das funcionalidades do core do Spring so:
O Mais completo lightweight container: Prove centralizao, automao de
configurao e escrita para seus objetos de negocio. um container no intrusivo,
capaz de suportar sistemas complexos de um conjunto de componentes (POJO) de
baixo acoplamento, consistncia e transparncia. O Container traz agilidade ao
desenvolvimento e tambm testabilidade e uma alta escalabilidade, permitindo que
os componentes de software possam ser desenvolvidos e testados isoladamente.
Pode ser utilizado em qualquer ambiente de desenvolvimento J2SE ou J2EE.
Uma camada comum de abstrao para Transaes: Permite gerenciamento
transacional plugvel com uma marcao transacional fcil, assim evitando
pequenos problemas de baixo nvel. Estratgias para JTA e para um nico JDBC
DataSource so includos. Em contraste com a JTA e o EJB CMT, as transaes do
spring no esto disponveis s em ambientes J2EE, possvel utilizar em ambiente
J2SE tambm.
Uma Camada de Abstrao para JDBC: Prove uma hierarquia de exceptions a
partir de SQLException de maneira totalmente significativa. Simplifica o tratamento
de erros, e diminuiu muito a quantidade de cdigo a ser escrito. Nunca mais ser
necessrio escrever um bloco finaly para usar JDBC.
Integrao com Toplink, Hibernate, JDO, and iBATIS SQL Maps: Em termos
de resource holders, suporte a implementaes de DAOs e estratgias transacionais.
Existe um suporte de primeira classe para Hibernate com muitas facilidades
providas pelo mecanismo de IoC.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-6
Funcionalidade AOP: Totalmente integrado com o gerenciamento
configuracional do Spring, voc pode utilizar AOP com qualquer objeto gerenciado
pelo Spring, adicionando aspectos em gerenciamento transacional, por exemplo.
Com Spring possvel ter transaes declarativas sem EJB e at mesmo sem JTA,
caso voc esteja utilizando um nico banco de dados em um servidor tomcat, por
exemplo.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-7
Cenrios de uso

Podemos utilizar Spring nos mais diversos cenrios, desde um simples applet
at mesmo nas mais complexas aplicaes corporativas. Um exemplo tpico de uso
do Spring em uma aplicao completa Java EE onde teremos:



Figura 1.2 Cenrio completo de uso em JEE.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-8
Uma camada de validaes de formulrios, solues em upload de arquivos,
bind de objetos de domnio e claro, uma integrao com JSP, Velocity, XSLT, PDF e
Excel. Aps isso o contexto web, gerenciado pelo Spring e utilizando o Spring MVC.
No cerne das aplicaes o contexto principal do Spring com o container IoC e
algumas funcionalidades, como envio de e-mails e acessos remotos atravs de RMI,
SOAP, Burlap, etc. Seguindo da camada de regras de negcio, onde temos
facilidades com o mdulo de AOP e a integrao com o mdulo de ORM, chegando
finalmente na camada de persistncia atravs do suporte rico ao Hibernate ou via
JDBC. Tudo isso rodando em um container JSP/Servlet como o Tomcat ou Jetty.
No caso de sua aplicao precisar fazer algum acesso remoto o Spring prove
isso de maneira transparente e elegante.


Figura 1.3 Cenrio remoto.
normal uma aplicao necessitar fazer acesso remoto a alguma outra
aplicao ou servio, nesse cenrio interessante usar spring tambm, pois alm de
facilitar a abstrair muito a complexidade de fazer esses acessos, voc pode usar os
seus componentes que j esto sendo gerenciados pelo spring obtendo assim uma
mxima integrao entre seus componentes de negcios e os componentes
remotos.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-9
Podemos usar Spring tambm se for necessrio fazer integrao com EJB,
possvel utilizar os recursos da camada de acesso e abstrao de EJB.


Figura 1.4 Cenrio EJB.

O Spring permite voc reutilizar seus pojos existentes e empacotados em
Stateless Session Beans, para serem usados em aplicaes web escalveis, que
precisam de segurana declarativa.
Spring Framework Framework para desenvolvimento de aplicaes java

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

O Spring possui um portiflio muito abrangente, que composto por uma
srie de projetos Spring..., podemos dizer que um ecossistema muito
diversificado, composto pelos seguintes projetos:
Spring Framework: Principal projeto do portiflio da Interface21, esse o
framework base de todos os outros. Contm recursos como container IoC, suporte a
Hibernate, jdbc, aop, integrao com os principais frameworks do mercado.
Spring Web Flow: framework web baseado em fluxos, prove a facilidade de
desenvolver modelos de aes dos usurios em alto nvel de abstrao. possvel
agrupar dois fluxos de controle e formar um modulo da juno dos dois.
Spring Web Services: Facilita o desenvolvimento de services SOAP,
permitindo a criao de web services flexveis, com suporte a segurana WS,
permitindo ecriptao, decriptao. Possui integrao com segurana ACGI. Alm
disso, o Spring Web Services faz as boas prticas serem fceis, ajudando voc
desenvolver com baixo acoplamento entre o contrato e a implementao.
Spring Acegi: Acegi uma soluo flexvel e poderosa para segurana de
aplicaes Java. Dentre as principais facilidades esto: autenticao, autorizao,
acesso baseado em instncia, canal de segurana e capacidades de deteco
humana. Utiliza o contexto do Spring para suas configuraes, configurao de
forma no intrusiva, utilizando filters.
Spring LDAP: Ajuda nas operaes LDAP, baseada no pattern Springs
JdbcTemplate. O Framework alivia o desenvolvedor de abrir e fechar contextos,
fazer loopings atravs de NamingEnumerations, encoding/deconding de valores e
filtros.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-11
Spring Rich Client: Framework para desenvolvimento de aplicaes Rich
Client, uma boa soluo para construes de aplicaes swing de maneira rpida
e de qualidade. Possu um conjunto rico de UI Factories, o foco desse projeto e
prover boas prticas de maneira vivel para o desenvolvimento swing, possui
integrao com Jgoodies e layout managers ricos como o TableLayout.
Spring IDE para eclipse: Plugin para o ide eclipse com facilidades para o uso
de Spring. Preove auto complete para os xmls de configurao do Spring, mdulo
visual para o Spring Web Flow, negao entre os beans do Spring, e visualizao de
recursos AOP.
Spring BeanDoc: uma ferramenta que facilita a documentao e desenho
grfico dos beans do contexto do Spring. Desenhado para ser flexvel e simples de
usar. BeanDoc pode facilitar a visualizao das camadas da aplicao e como os
objetos interagem. Pode ser configurado por uma task ant.
Spring OSGI: Facilita a criao de aplicaes Spring que iro rodar em um
framework OSGI, uma aplicao escrita dessa forma tem uma separao melhor
entre os mdulos, com isso ganha a habilitada de remover, adicionar, atualizar os
mdulos em tempo de execuo.
Spring JavaConfig: Projeto que prove algumas anotaes para efetuar o
mapeamento de pojos com menos configuraes em XML. Esse projeto no
substitui completamente o uso de XML, mas consegue reduzir bastante em algumas
funcionalidades de injeo.
Spring.NET: Implementao do Core do Spring, com o seu container de IoC,
s que para a plataforma da Microsoft .NET, esse projeto no tem todas as
funcionalidades do Spring para Java, mas conta com muitos recursos do Spring
feitos em Java como AOP, gerenciamento transacional e integrao com Web.
Spring Extensions: Projeto que uma coleo de ferramentas para estender
as funcionalidades do Spring framework, prove facilidade de integrar o Spring com
outros frameworks. Dentre os tantos frameworks que so integrados com esse
projeto esto: ant, Lucene, cache declarativo com EHCache, Drools, Jakarta
Commons, engines de tamplates como Velocity, jBPM, etc.
Spring Batch: Prove suporte para execuo de tarefas muito longas. Suporte
a programas batch os quais processam um volume muito grande de informaes de
um banco de dados. Com suporte a agendamento automtico ou manual aps
falhas, esse projeto promove suporte de execues batch para ambientes
corporativos.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-12
Download
O Spring Framework pode ser obtido atravs do site:
http://www.springframework.org/download existe a possibilidade de baixar
somente o framework ou baixar o framework e suas dependncias. A Verso do
Spring que ser usada nessa apostila a 2.0.6 , mas muitos itens descritos aqui so
vlido tambm para a verso 1.2.x do framework.
O Spring framework necessita apenas uma verso do 1.5 JDK ou superior,
no necessrio criar variveis de ambiente para o Spring. O Spring usa um
conjunto de frameworks muito grande, ento recomendado fazer download da
verso full com dependncia que tem por volta de 60Mb.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-13
Estrutura de Diretrios

Agora ser detalhada a estrutura de diretrios da distribuio do Spring
framework. Ao descompactar os binrios do Spring teremos uma estrutura de
diretrios da seguinte forma:


Figura 1.4 Estrutura de Diretrios da distribuio do Spring.

aspectj: Fontes dos testes dos artefatos que utilizam aspectj, aqui temos
alguns artefatos de transao feitos em aspectJ.
dist: Distribuio binrias dos fontes do Spring, aqui voc encontrar os jars
do Spring, bem como todos os jars de todos os mdulos separados.
docs: Contem toda a documentao do Spring, nessa voc ir encontrar o
JavaDoc, Reference Guide, documentao das taglibs do Spring.
lib: Nesse diretrio esto todas as dependncias diretas e indiretas do Spring
framework, aqui voc encontrar jars de diversos frameworks, como por exemplo
hibernate, struts, junit, ant.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-14
mock: Fontes do mecanismo de mock que so utilizados para testes
unitrios, nesse diretrio voc encontra os fontes dos testes dos mocks tambm.
samples: Nesse diretrio existem diversos exemplos de mini-aplicaes
utilizando o Spring Framework, como por exemplo a Petclinic que uma clinica de
animais.
src: Contm todos os fontes do Spring framework, caso voc precise desses
fontes para debugar o comportamento de algum cdigo do Spring.
test: Nesse diretrio voc encontrar todos os fontes dos testes realizados
com o Spring, til para aprender como utilizar algumas classes do Spring.
tiger: Todos os fontes que utilizam recursos somente do Java 5.0 esto nesse
diretrio, como por exemplo, annotations.

Dois arquivos que esto soltos no diretrio principal e so interessantes so
o changelog.txt e o readme.txt. No arquivo changelog contm todas as mudanas
dessa verso do Spring como, por exemplo: quais so as novas features e quais
foram os bugs corrigidos. No arquivo readme ns temos a definio de cada
modulo do Spring com suas dependncias, isso muito til se voc deseja utilizar
somente alguns mdulos do Spring e precisa saber as dependncias.
Spring Framework Framework para desenvolvimento de aplicaes java

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

1) Defina com suas palavras qual a utilidade do Spring Framework.
2) Cite trs vantagens de se usar Spring framework.
3) Diga um cenrio em que poderamos utilizar Spring.
4) Diga uma das utilidades do arquivo readme.txt.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 1-16
Espao para anotaes
Spring Framework Framework para Desenvolvimento de Aplicaes Java

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


C
C
o
o
n
n
t
t
a
a
i
i
n
n
e
e
r
r
I
I
o
o
C
C

Spring Framework Framework para desenvolvimento de aplicaes java

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

Conhecer o conceito de IoC;
Saber utilizar Lazy initialization e Singletons;
Conhecer os escopos dos Beans;
Saber registrar beans no container do Spring;
Saber fazer injees com setters e construtores;
Saber fazer injees com colees;
Saber fazer injeo entre beans colaboradores;
Saber instanciar o contexto do Spring.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-3
IoC Inversion of control

Com a grande demanda de desenvolvimento para o Java corporativo (JEE),
surgiu um problema comum, como ligar a camada de acesso a dados com a camada
de regra de negcio e por ventura a camada de apresentao? Uma soluo um
container de Ioc que tambm chamada de Dependency Injection(DI), o Spring
framework possui um container de Ioc leve e implementa o pattern de setter
injection.
Esse container trabalha com servios definidos pelo programador. Servio
um componente de software que foi projetado para ser reutilizado em muitos lugares
sem a necessidade de alterao de cdigo, possvel alterar o seu comportamento
estendendo-o de alguma forma. A Idia principal da injeo de dependncias
separar os Objetos e principalmente o objeto que usa um outro objeto no instanciar
diretamente esse objeto. Sendo assim, a principal vantagem da Dependency Injection
separar uma interface de sua implementao concreta.
So dois tipos de injeo que o Spring utiliza em seu container de Ioc, veja:
Setter Injection: Nesse tipo de injeo de dependncias se utiliza de mtodos
setters baseados em propriedades e padres de getters/setters da Sun. Voc no
precisa ter a propriedade de fato em seu servio, mas o padro de nomenclatura
deve estar correto.
Constructor Injection: Nesse tipo de injeo de dependncias utilizado o
construtor da prpria classe para fazer as injees necessrias. Esse construtor pode
ter quantos parmetros forem necessrios.
Principais vantagens do uso de IoC do Spring:
Desacoplamento
Viso fcil de dependncia
Facilidade para testes
Possibilita escrever aplicaes para terceiros (fora do seu controle)
Para fixar melhor esse conceito considere o seguinte exemplo pratico: Imagine
que um Autor escreveu muitos livros, ento considere os seguintes pojos:
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.bad;

import java.util.List;

public class Autor {

private String nome;
private List<Livro> livros;

public Autor() {}

public Autor(String nome) {
super();
this.nome = nome;
}

public void listarPorNome(){
Listar l = new Listar();
List ret = l.list(nome);
System.out.println( (ret.size()==0) ? "NRE" : ret );
}

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

public List<Livro> getLivros() {
return livros;
}
public void setLivros(List<Livro> livros) {
this.livros = livros;
}
}
Cdigo 2.1 Autor.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.bad;

public class Livro {


private Autor autor;
private String titulo;
private String editora;
private int ano;



public Livro() {}

public Livro(Autor autor, String titulo, String editora, int ano) {
super();
this.autor = autor;
this.titulo = titulo;
this.editora = editora;
this.ano = ano;
}

public Autor getAutor() {
return autor;
}
public void setAutor(Autor autor) {
this.autor = autor;
}

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

public String getEditora() {
return editora;
}
public void setEditora(String editora) {
this.editora = editora;
}

public int getAno() {
return ano;
}
public void setAno(int ano) {
this.ano = ano;
}

@Override
public String toString() {
return "titulo: " + titulo + " editor: " + editora +
" ano: " + ano;
}

}
Cdigo 2.2 Livro.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.bad;

import java.util.ArrayList;
import java.util.List;

public class Listar {

public List list(String nome){

Autor a = new Autor("Diego Pacheco");

List<Livro> livros = new ArrayList<Livro>();
livros.add(new Livro(a,"Livro da Vida","Do Livro",2000));
livros.add(new Livro(a,"Spring for Dummies","O'really",2001));
livros.add(new Livro(a,"Bit ou no","Variados Editora",2002));


List<Livro> achados = new ArrayList<Livro>();

for(Livro l: livros){
if (l.getAutor().getNome().equals(nome))
achados.add(l);
}
return achados;
}

}

Cdigo 2.3 Listar.java

package com.targettrust.spring.bad;

public class MainTest {

public static void main(String[] args) {
Autor autor = new Autor("Rod");
autor.listarPorNome();

autor.setNome("Diego Pacheco");
autor.listarPorNome();
}

}
Cdigo 2.4 MainTest.java
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-7
Ns temos os seguintes objetos: Autor, Livro, Listar e MainTest. Nesse exemplo
um Autor pode ter vrios livros por isso dentro do Pojo de Autor temos List<Livro>
e a classe Listar se encarrega de armazenar os livros e autores e prover uma procura
sobre esses dados. Como vocs devem ter percebido o pojo Autor contm um
mtodo chamado: listarPorNome que instncia esse objeto Listar e procura pelos
livros do autor. Esse exemplo por mais simplrio, serve para demonstrar que existe
um forte acoplamento entre o pojo Autor e a classe que lista os Livros por Autor,
outro grande problema nesse exemplo que no existem interfaces. O que
aconteceria se um Autor pudesse ter outras coisas alm de livros como, por exemplo:
artigos, co-autorias, vdeos? Nesse caso essa mudana iria implicar em um refactoring
muito grande nessas classes, mas como poderamos resolver esse problema?
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-8
Soluo: Criar um interface Publicvel e o Livro ir implementar essa classe, no
pojo de Autor mude de uma lista de Livros para uma List de Publicveis, assim
criamos a possibilidade de um Autor ter diversos itens em seu portiflio como, por
exemplo: Livros, Artigos, Co-autuaes. Para resolver o problema de forma de
armazenamento e procura de livros, foi criada a interface Listavel e a classe Listar
implementa essa interface, agora podemos criar outra classe que faa acesso base
de dados, claro que esse classe deve implementar Listavel. No pojo do Autor
precisamos colocar um atributo Listavel e atravs desse atributo que vamos acessar
os dados. Essas novas classes iram ficar conforme os fontes a baixo.
package com.targettrust.spring.bad.ok;

import java.util.List;

public class Autor {

private String nome;
private List<Publicavel> publicaveis;
private Listavel list;

public Autor() {}

public Autor(String nome) {
super();
this.nome = nome;
}

public void listarPorNome(){
List ret = list.list(nome);
System.out.println( (ret.size()==0) ? "NRE" : ret );
}

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

public List<Publicavel> getPublicaveis() {
return publicaveis;
}
public void setPublicaveis(List<Publicavel> publicaveis) {
this.publicaveis = publicaveis;
}

public Listavel getList() {
return list;
}
public void setList(Listavel list) {
this.list = list;
}
}
Cdigo 2.5 Autor.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.bad.ok;

public class Livro implements Publicavel{

private Autor autor;
private String titulo;
private String editora;
private int ano;

public Livro() {}

public Livro(Autor autor, String titulo, String editora, int ano) {
super();
this.autor = autor;
this.titulo = titulo;
this.editora = editora;
this.ano = ano;
}

@Override
public String getNome() {
return getTitulo();
}

@Override
public String getTipo() {
return "Livro";
}

public String getAutor() {
return autor.getNome();
}
public void setAutor(Autor autor) {
this.autor = autor;
}

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

public String getEditora() {
return editora;
}
public void setEditora(String editora) {
this.editora = editora;
}

public int getAno() {
return ano;
}
public void setAno(int ano) {
this.ano = ano;
}

@Override
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-10
public String toString() {
return "titulo: " + titulo + " editor: " + editora +
" ano: " + ano;
}

}
Cdigo 2.6 Livro.java
package com.targettrust.spring.bad.ok;

public interface Publicavel {
public String getAutor();
public String getNome();
public String getTipo();
}
Cdigo 2.7 Publicavel.java
package com.targettrust.spring.bad.ok;

import java.util.List;

public interface Listavel {
public List<Publicavel> list(String nome);
}
Cdigo 2.8 Listavel.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.bad.ok;

import java.util.ArrayList;
import java.util.List;

public class Listar implements Listavel{

public List<Publicavel> list(String nome) {

Autor a = new Autor("Diego Pacheco");

List<Publicavel> publicaveis = new ArrayList<Publicavel>();
publicaveis.add(new Livro(a,"Livro da Vida","Do Livro",2000));
publicaveis.add(new Livro(a,"Spring for
Dummies","O'really",2001));
publicaveis.add(new Livro(a,"Bit ou no","Variados
Editora",2002));

List<Publicavel> achados = new ArrayList<Publicavel>();

for(Publicavel p: publicaveis){
if (p.getAutor().equals(nome))
achados.add(p);
}
return achados;
}

}
Cdigo 2.9 Listar.java
package com.targettrust.spring.bad.ok;

public class MainTest {

public static void main(String[] args) {
Autor autor = new Autor();
autor.setList(new Listar());

autor.setNome("Rod");
autor.listarPorNome();

autor.setNome("Diego Pacheco");
autor.listarPorNome();
}

}

Cdigo 2.10 MainTest.java


Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-12
Nesse exemplo conseguimos resolver os problemas citados acima, mas
utilizamos a IoC na mo, ou seja, ns mesmos injetamos as dependncias, a soluo
boa, mas isso em um sistema grande seria muito custoso de se fazer, nesse ponto
entra o container de IoC do Spring. O Container possibilita de maneira fcil e simples
a injeo dessas dependncias e reduz o custo de se trabalhar com essas interfaces
quase zero.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-13
Registrando Beans

Agora vamos ver como registrar essas classes no contexto do Spring. Esse
registro muito simples, ele consiste em apontar para uma classe Java no seu
classpath e dar um id a esse bean. Existem outras configuraes que podemos fazer
sobre esses beans, mas vamos comear mostrando como declarar um bean no
Spring.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="autor"
class="com.targettrust.spring.bad.ok.Autor"
/>

</beans>
Cdigo XML 2.1 Spring-beans.xml
Para recuperarmos esse bean do Contexto do Spring, precisamos instanciar um
contexto do Spring e solicitar o bean apartir do ID para o contexto, conforme
exemplo a baixo.
package com.targettrust.spring.primeiro;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/primeiro/Spring-
beans.xml");
Object bean = bf.getBean("autor");
System.out.println("Autor: " + bean);
}
}
Cdigo 2.11 Obtendo um bean do Spring
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-14
A BeanFactory uma interface Java que representa o Container Ioc, essa
BeanFactory precisa ser instanciada, nesse exemplo foi usado a factory
ClassPathXmlApplicationContext que uma factory que leva em considerao xmls
de configuraes que esto no classpath. Existem vrias factories no Spring, uma para
cada situao, por exemplo, existe uma factory que utilizada para subir o contexto
do Spring em um ambiente Servlet.
Aps a inicializao do contexto do Spring podemos utilizar o mtodo getBean
para recuperar um bean do Spring, nesse exemplo estamos passando o ID do bean
que foi o mesmo que registramos no XML: Spring-beans.xml
Outra forma de criarmos a BeanFactory seria utilizar um ClassPathResource
que aponta para o Xml dos beans e depois utilizar a factory XmlBeanFactory.
Conforme o exemplo de cdigo a baixo.
ClassPathResource resource = new
ClassPathResource("/com/targettrust/spring/primeiro/Spring-beans.xml");
BeanFactory bf = new XmlBeanFactory(resource);
Cdigo 2.12 outra bean factory
possvel registrar um Bean no contexto do Spring programaticamente, para
isso necessrio utilizar um objeto BeanDefinition que o objeto que configura o
bean no Spring.
BeanDefinition beanDefinition = new RootBeanDefinition(Livro.class,
RootBeanDefinition.AUTOWIRE_NO);
((BeanDefinitionRegistry)bf).registerBeanDefinition("livro",
beanDefinition);

Object beanOutro = bf.getBean("livro");
System.out.println("Livro: " + beanOutro);
Cdigo 2.13 Registra um bean programaticamente
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-15
Singletons e lazy Initialization

Para aumentar a performance de sua aplicao com qualidade e aplicando
design patterns o Spring por default transforma qualquer bean registrado nele em
um singleton. Singleton um padro de projeto (Design Pattern) que consiste em
manter apenas uma instncia de um determinado objeto por classloader. um
pattern muito aplicado para conexes com banco de dados, por exemplo. Podemos
ver isso atravs do seguinte teste.
package com.targettrust.spring.singleton;

import java.util.ArrayList;
import java.util.List;

public class Uf {

private String nome;
private String sigla;
private List<Uf> ufs;

public Uf() {
System.out.println("Inicio do processamento dos estados...");
initUfs();
}

private Uf(String nome, String sigla) {
this.nome = nome;
this.sigla = sigla;
}

private void initUfs() {
ufs = new ArrayList<Uf>();
ufs.add(new Uf("Acre","AC"));
ufs.add(new Uf("Alagoas","AL"));
ufs.add(new Uf("Amap","AP"));
ufs.add(new Uf("Amazonas","AM"));
ufs.add(new Uf("Bahia","BA"));
ufs.add(new Uf("Cear","CE"));
ufs.add(new Uf("Distrito Federal","DF"));
ufs.add(new Uf("Gois","GO"));
ufs.add(new Uf("Esprito Santo","ES"));
ufs.add(new Uf("Maranho","MA"));
ufs.add(new Uf("Mato Grosso","MT"));
ufs.add(new Uf("Mato Grosso do Sul","MS"));
ufs.add(new Uf("Minas Gerais","MG"));
ufs.add(new Uf("Par","PA"));
ufs.add(new Uf("Paraiba","PB"));
ufs.add(new Uf("Paran","PR"));
ufs.add(new Uf("Pernambuco","PE"));
ufs.add(new Uf("Piau","PI"));
ufs.add(new Uf("Rio de Janeiro","RJ"));
ufs.add(new Uf("Rio Grande do Norte","RN"));
ufs.add(new Uf("Rio Grande do Norte","RS"));
ufs.add(new Uf("Rondnia","RO"));
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-16
ufs.add(new Uf("Rorima","RR"));
ufs.add(new Uf("So Paulo","SP"));
ufs.add(new Uf("Santa Catarina","SC"));
ufs.add(new Uf("Sergipe","SE"));
ufs.add(new Uf("Tocantins","TO"));
}

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

public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}

public List<Uf> getUfsBrazil(){
return ufs;
}

public void showInstance(){
System.out.println(super.toString());
}

public String toString() {
return sigla;
}
}
Cdigo 2.14 Bean Uf
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="uf"
class="com.targettrust.spring.singleton.Uf"
/>

</beans>
Cdigo XML 2.2 Spring-beans.xml
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.singleton;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestUfs {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/singleton/Spring-
beans.xml");

Uf bean1 = (Uf)bf.getBean("uf");
System.out.println("ufs: " + bean1.getUfsBrazil());
bean1.showInstance();

Uf bean2 = (Uf)bf.getBean("uf");
System.out.println("ufs: " + bean2.getUfsBrazil());
bean2.showInstance();

Uf bean3 = (Uf)bf.getBean("uf");
System.out.println("ufs: " + bean3.getUfsBrazil());
bean3.showInstance();

}
}
Cdigo 2.15 Teste
Se executarmos esse programa, o resultado ser algo semelhante ao
representado na figura abaixo.
Inicio do processamento dos estados...
ufs: [AC, AL, AP, AM, BA, CE, DF, GO, ES, MA, MT, MS, MG, PA, PB, PR, PE,
PI, RJ, RN, RS, RO, RR, SP, SC, SE, TO]
com.targettrust.spring.singleton.Uf@3ecfff
ufs: [AC, AL, AP, AM, BA, CE, DF, GO, ES, MA, MT, MS, MG, PA, PB, PR, PE,
PI, RJ, RN, RS, RO, RR, SP, SC, SE, TO]
com.targettrust.spring.singleton.Uf@3ecfff
ufs: [AC, AL, AP, AM, BA, CE, DF, GO, ES, MA, MT, MS, MG, PA, PB, PR, PE,
PI, RJ, RN, RS, RO, RR, SP, SC, SE, TO]
com.targettrust.spring.singleton.Uf@3ecfff
Cdigo 2.16 Resultado da Execuo
Perceba que a criao dos estados ocorre somente na primeira vez, mas nas
outras vezes j est em memria, logo alm, se no fizer duas vezes o mesmo
processamento, existe um ganho de performance.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Tambm possvel desativar esse comportamento, ou seja, possvel
configurar no spring para que o bean em questo no seja criado como um
Singleton. Para isso, basta alterar o registro do bean no Spring, conforme no XML
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="uf"
class="com.targettrust.spring.singleton.Uf"
scope="prototype"
/>

</beans>
Cdigo XML 2.3 Spring-beans.xml
Neste mesmo captulo sero explicados e exemplificados melhor os possveis
escopos de beans no Spring.

Lazy Initialization
Outro recurso importante o Lazy Initialization, com ele podemos fazer com
que o Spring s carregue os beans que forem solicitados, ou seja, se temos 50 beans
declarados no contexto do Spring e apenas 10 so utilizados, os outros 40 beans no
vo ser instanciados, e assim evitamos um processamento desnecessrio e ganhamos
em desempenho.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-19
Para fazer tal configurao necessrio configurar no XML de beans do Spring
o atributo lazy-init="true". Veja o exemplo de como faz isso no XML 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>




<bean
id="uf"
class="com.targettrust.spring.singleton.Uf"
scope="prototype"
lazy-init="true"
/>

</beans>
Cdigo XML 2.4 Spring-beans.xml um exemplo lazy initialization.
sempre vlido configurar esse comportamento do framework. O Default do
Spring comear com lazy-init=false, ento sempre que possvel altere essa
configurao para true.
Podemos configurar no Spring que todos os beans de um determinado
arquivo XML de configuraes por default assumam o mesmo valor, podemos fazer
isso atravs do atributo default-lazy-init esse atributo s pode ser setado no modo
beans que a raiz de configuraes.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="uf"
class="com.targettrust.spring.singleton.Uf"
scope="prototype"
/>

</beans>
Cdigo XML 2.4 Spring-beans.xml um exemplo de default lazy initialization.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-20
Scopos dos Beans

Scopo se refere visibilidade de um objeto gerenciado pelo Spring e tambm
est relacionado ao seu tempo de vida. Existem os seguintes scopos de beans no
Spring.
Scopo Descrio
singleton Uma nica instncia de objeto para todo o contexto do Spring.
prototype Mltiplas instncias de um objeto para o container do Spring.
request * Escopo relacionado ao ciclo de vida HTTP Request, a cada
request teremos outra instncia de bean no Spring
session * Escopo relacionado ao ciclo de vida HTTP Session, uma nica
instncia do Bean por session.
global
session *
Escopo relacionado ao ciclo de vida global HTTP Session, bean
vlido em uma session global. Utilizado para portlets.
* Escopos que s so vlidos em um contexto web-aware, ou seja, em uma aplicao
JSP/Servlet ou JEE. Criados por uma factory especfica para Web, como por exemplo:
XmlWebApplicationContext.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-21
Podemos ver na prtica a diferena entre singleton e prototype no exemplo
abaixo. Nesse exemplo o mesmo bean registrado de maneiras diferentes, isso
perfeitamente possvel.

package com.targettrust.spring.scope;

public class SimpleBean {

private Long id = 0L;

public SimpleBean() {}

public SimpleBean(Long id) {
super();
this.id = id;
}

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

@Override
public String toString() {
return super.toString() + " id: " + id;
}
}

Cdigo 2.17 SimpleBean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="beanA"
class="com.targettrust.spring.scope.SimpleBean"
scope="singleton"
/>

<bean
id="beanB"
class="com.targettrust.spring.scope.SimpleBean"
scope="prototype"
/>

</beans>
Cdigo XML 2.5 Spring-beans.xml xml de configurao.
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.scope;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestScope {

public static void main(String[] args) {

BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/scope/Spring-
beans.xml");

SimpleBean beanA = (SimpleBean)bf.getBean("beanA");
SimpleBean beanA1 = (SimpleBean)bf.getBean("beanA");
SimpleBean beanB = (SimpleBean)bf.getBean("beanB");
SimpleBean beanB1 = (SimpleBean)bf.getBean("beanB");

System.out.println("BeanA : " + beanA);
System.out.println("BeanA1 : " + beanA1);
System.out.println("BeanB : " + beanB);
System.out.println("BeanB1 : " + beanB1);

}

}
Cdigo 2.18 Teste de Scopes.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-23
Criando seu prprio scope
No Spring framework 2.0.X podemos criar nosso prprio scope e ainda mais,
podemos redefinir os scopos baseados em web-aware. Os nicos scopos que so
intocveis so: prototype e singleton, se tentarmos reescrev-los o Spring ir levantar
uma IllegalArgumentException.
Imagine que em sua aplicao surgiu a necessidade de ter controle sobre
todos os objetos Pessoa criados, como poderamos fazer isso sem reescrever toda a
aplicao? Criando o nosso prprio scopo de bean seria uma forma.
package com.targettrust.spring.scope.myscope;

public class Pessoa {

private String nome;

public Pessoa() {
}

public Pessoa(String nome) {
super();
this.nome = nome;
}

public String getNome() {
return nome;
}

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

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((nome == null) ? 0 :
nome.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
return (obj == null) ? false : nome.equals(((Pessoa)
obj).getNome());
}

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

}
Cdigo 2.19 Pessoa.java.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-24
package com.targettrust.spring.scope.myscope;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@SuppressWarnings("unused")
public class TestScopes {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/scope/myscope/Spri
ng-beans.xml");

Pessoa p1 = (Pessoa)bf.getBean("pessoa1");
Pessoa p2 = (Pessoa)bf.getBean("pessoa2");
Pessoa p3 = (Pessoa)bf.getBean("pessoa3");
Pessoa p4 = (Pessoa)bf.getBean("pessoa4");
System.out.println("Todas as pessoas: " +
ThreadLocalScope.tl.get());

p3.setNome("Spider-Pig");
System.out.println("Todas as pessoas: " +
ThreadLocalScope.tl.get());
}
}
Cdigo 2.20 Classe de testesTestScopes.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
default-lazy-init="false"
>
<bean
class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="threadLocal">
<bean
class="com.targettrust.spring.scope.myscope.ThreadLocalScope"/>
</entry>
</map>
</property>
</bean>

<bean id="pessoa1"
class="com.targettrust.spring.scope.myscope.Pessoa"
scope="threadLocal"
>
<property name="nome" value="Diego Pacheco"/>
</bean>

<bean id="pessoa2"
class="com.targettrust.spring.scope.myscope.Pessoa"
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-25
scope="threadLocal"
>
<property name="nome" value="Rod Johnson"/>
</bean>

<bean id="pessoa3"
class="com.targettrust.spring.scope.myscope.Pessoa"
scope="threadLocal"
>
<property name="nome" value="Juergen Hoeller"/>
</bean>

<bean id="pessoa4"
class="com.targettrust.spring.scope.myscope.Pessoa"
scope="singleton"
>
<property name="nome" value="Ninguem me viu!!!"/>
</bean>

</beans>
Cdigo XML 2.6 Spring-beans.xml scope customizado.
package com.targettrust.spring.scope.myscope;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class ThreadLocalScope implements Scope{

public static ThreadLocal<Map<String, Object>> tl;

public ThreadLocalScope() {
tl = new ThreadLocal<Map<String,Object>>();
tl.set(new HashMap<String, Object>());
}

@Override
public Object get(String name, ObjectFactory objectFactory) {

synchronized(tl){

Object realTarget = objectFactory.getObject();
if (realTarget instanceof Pessoa){
tl.get().put(realTarget.hashCode() + ";",
realTarget);
return realTarget;
}

throw new RuntimeException("Esse scopo s pode ser
utilizado para objetos Pessoa ");
}
}

@Override
public Object remove(String name) {
synchronized(tl){
Object obj = tl.get().remove(name);
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-26
return obj;
}
}

@Override
public void registerDestructionCallback(String name, Runnable
callback){
throw new UnsupportedOperationException("Essa operao de
registerDestructionCallback, no suportada!");
}

@Override
public String getConversationId() {
return null;
}
}
Cdigo 2.21 ThreadLocalScope.java classe de scope customizada.

Para criar um scopo personalizado no Spring necessrio implementar a
interface org.springframework.beans.factory.config.Scope, a implementao
dessa interface simples, basicamente s precisamos nos preocupar com os mtodos
get e remove. Aps a implementao dessa interface s ser necessrio registrar no
spring o seu novo scopo, isso feito com a seguinte configurao em xml:
<bean
class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="threadLocal">
<bean
class="com.targettrust.spring.scope.myscope.ThreadLocalScope"/>
</entry>
</map>
</property>
</bean>
Cdigo XML 2.7 Definio de scope customizado.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-27
Injeo via setter

Essa uma das duas formas que o Spring faz injeo de dependncias, ele
utiliza um mtodo setter conforme padro da Sun e atravs desse mtodo setta os
valores no objeto em questo.

package com.targettrust.spring.setter;

public class Aluno {

private String nome;
private Integer idade;
private boolean desconto;
private Character sexo;

public Aluno() {}

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

public Integer getIdade() {
return idade;
}
public void setIdade(Integer idade) {
this.idade = idade;
}

public boolean isDesconto() {
return desconto;
}
public void setDesconto(boolean desconto) {
this.desconto = desconto;
}

public Character getSexo() {
return sexo;
}
public void setSexo(Character sexo) {
this.sexo = sexo;
}

@Override
public String toString() {
return "nome: " + nome +
" idade: " + idade +
" desconto: " + desconto +
" sexo: " + sexo;
}
}
Cdigo 2.22 Aluno.java.
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="aluno"
class="com.targettrust.spring.setter.Aluno"
>
<property name="nome" value="Diego" />
<property name="idade" value="22" />
<property name="desconto" value="true" />
<property name="sexo" value="M" />
</bean>
</beans>
Cdigo XML 2.8 Configurao de injeo via setter
package com.targettrust.spring.setter;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSetter {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/setter/Spring-
beans.xml");

System.out.println(bf.getBean("aluno"));
}
}
Cdigo 2.23 TestSetter.java

No existe nada de mgico na injeo via setter, simples, basta ter o mtodo
setter e o tipo de dado injetado ser o mesmo.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-29
Injeo via construtor
Esta a outra forma de injeo de dependncia do Spring. As dependncias
so injetadas atravs de um construtor. Considere a seguinte classe Java:

package com.targettrust.spring.constructor;

public class Pessoa {

private String nome;
private Integer idade;
private boolean cartaMorotista;

public Pessoa(String nome, Integer idade, boolean cartaMorotista) {
super();
this.nome = nome;
this.idade = idade;
this.cartaMorotista = cartaMorotista;
}

@Override
public String toString() {
return " nome: " + nome +
" idade: " + idade +
" morotista: " + cartaMorotista;
}

}
Cdigo 2.24 Pessoa.java

Para injetarmos nome, idade, cartaMotorista, s efetuar essa injeo via
construtor no XML de configurao do Spring, conforme cdigo XML 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="pessoa"
class="com.targettrust.spring.constructor.Pessoa"
>
<constructor-arg value="Diego Pacheco" />
<constructor-arg value="22" />
<constructor-arg value="false" />
</bean>
</beans>
Cdigo XML 2.9 Configurao de injeo via construtor
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-30
Para ver a injeo funcionando considere a classe de testes abaixo:

package com.targettrust.spring.constructor;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestConstructor {

public static void main(String[] args) {

BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/constructor/Spring
-beans.xml");

System.out.println(bf.getBean("pessoa"));
}
}
Cdigo 2.25 TestConstructor.java Teste de construtor

Ao rodar esses cdigos voc ter um retorno semelhante a este:

nome: Diego Pacheco idade: 22 motorista: false
Caso voc tenha um construtor que receba uma String e um nmero, o Spring
pode acabar sentando valores indesejados, para resolver esse tipo de situao,
podemos especificar o tipo do argumento do construtor, conforme exemplo de XML
abaixo.

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="7500000"/>
<constructor-arg type="java.lang.String" value="42"/>
</bean>
Cdigo XML 2.10 Exemplo de tipo de argumento para construtor.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-31
Uma outra opo seria informar qual a posio do parmetro no construtor,
isso ns chamamos de index, comea em zero(0), como segue o exemplo:

<bean
id="animal"
class="com.targettrust.spring.constructor.Animal"
>
<constructor-arg index="1" value="Black" />
<constructor-arg index="0" value="Dog" />
</bean>
Cdigo XML 2.11 Exemplo de tipo de argumento para construtor com index.

Injeo de colees
Por deafult o Spring possui tags especficas para injeo de colees, possvel
injetar: Map, List, Properties e Set. De fato podemos injetar qualquer Collection, mas
para injetar uma coleo que no seja uma das citadas, ser necessrio usar um
Custon Property Editor. Para fazer as injees das colees nativas do Spring,
utilizamos as tags: <map/>, <list/>, <set/> e <props/>. Considerando o seguinte
exemplo:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="estadio"
class="com.targettrust.spring.collection.Estadio"

>

<property name="pessoas">
<set>
<value>Diego</value>
<value>Rod</value>
<value>Alef</value>
</set>
</property>

<property name="cadeiras">
<map>
<entry>
<key><value>1</value></key>
<value>diego</value>
</entry>
<entry>
<key><value>2</value></key>
<value>Rod</value>
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-32
</entry>
</map>
</property>

<property name="vededoresPipoca">
<list>
<value>Ze</value>
<value>JoZe</value>
<value>MaisEh</value>
</list>
</property>







<property name="detalhes">
<value>
estadio.luz=forte
estadio.taman.hq.full=grande
estadio.fundac.since=10/10/2001
estadio.status.now=ativo
</value>
</property>

</bean>
</beans>
Cdigo XML 2.12 Exemplo de injeo de collections.

Para esse cdigo de injees de colees em XML precisamos de uma classe
Java, conforme a definida a baixo:

package com.targettrust.spring.collection;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Estadio {

private Set<String> pessoas;
private Map<Integer, String> cadeiras;
private List<String> vededoresPipoca;
private Properties detalhes;

public Estadio() {}

public Set<String> getPessoas() {
return pessoas;
}
public void setPessoas(Set<String> pessoas) {
this.pessoas = pessoas;
}

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-33
public Map<Integer, String> getCadeiras() {
return cadeiras;
}
public void setCadeiras(Map<Integer, String> cadeiras) {
this.cadeiras = cadeiras;
}

public List<String> getVededoresPipoca() {
return vededoresPipoca;
}
public void setVededoresPipoca(List<String> vededoresPipoca) {
this.vededoresPipoca = vededoresPipoca;
}

public Properties getDetalhes() {
return detalhes;
}
public void setDetalhes(Properties detalhes) {
this.detalhes = detalhes;
}

@Override
public String toString() {
return " pessoas: " + pessoas + "\n" +
" cadeiras: " + cadeiras + "\n" +
" Vededores de Pipoca: " + vededoresPipoca + "\n" +
" detalhes: " + detalhes;
}
}

Cdigo 2.26 Estadio.java Classe que usa Collections.

Podemos testar esses recursos atravs do teste abaixo:

package com.targettrust.spring.collection;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestCollections {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/collection/Spring-
beans.xml");
System.out.println(bf.getBean("estadio"));
}
}
Cdigo 2.26 TestCollections.java Classe de testes.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-34
Existem outras vriaveis para a injeo de properties, no exemplo acima foi
utilizada a forma mais simplificada, mas poderamos fazer da forma completa,
conforme exemplo abaixo:

<property name="detalhes">
<props>
<prop key="estadio.luz">forte</prop>
<prop key="estadio.taman.hq.full">grande</prop>
<prop key="estadio.fundac.since">10/10/2001</prop>
<prop key="estadio.status.now">ativo</prop>
</props>
</property>
Cdigo XML 2.13 Outra forma de injeo de Properties.

Dica: Se for explicitamente necessrio injetar uma coleo nula, ou settar null em
alguma propriedade de algum bean do Spring, podemos utilizar a tag <null/>.

Podemos injetar qualquer tipo de coleo atravs do uso de property editors,
essa uma soluo muito elegante do Spring. Quando registramos um editor do tipo
Class, por exemplo, toda vez que o Spring for injetar um valor em um objeto que a
propriedade seja Class ele vai invocar esse property editor. Veja como usar a
Collection do Tipo LinkedList no exemplo abaixo:

package com.targettrust.spring.collection;

import java.util.LinkedList;

public class Cidade {

private LinkedList<String> ruas;

public Cidade() {}

public LinkedList<String> getRuas() {
return ruas;
}
public void setRuas(LinkedList<String> ruas) {
this.ruas = ruas;
}
}
Cdigo 2.27 Cidade.java Classe que usa LinkedList.
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer"
>
<property name="customEditors">
<map>
<entry key="java.lang.Class">
<bean
class="org.springframework.beans.propertyeditors.ClassEditor" />
</entry>
<entry key="java.util.LinkedList">
<bean
class="org.springframework.beans.propertyeditors.CustomCollectionEditor">
<constructor-arg
index="0"><value>java.util.LinkedList</value></constructor-arg>
<constructor-arg
index="1"><value>true</value></constructor-arg>
</bean>
</entry>
</map>
</property>
</bean>

<bean
id="cidade"
class="com.targettrust.spring.collection.Cidade"
>
<property name="ruas">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
</bean>

</beans>
Cdigo XML 2.14 Uso de PropertyEditors.

Nesse exemplo foi registrado um property editor de class, chamado:
org.springframework.beans.propertyeditors.ClassEditor, que est associado ao
tipo Class.
Esse property editor necessrio para o property editor de Collections:
org.springframework.beans.propertyeditors.CustomCollectionEditor.
O Property editor de Collections tem dois parmetros no construtor, o
primeiro a classe que a collection deve ser, e o segundo um boolean indicando se
deve ser convertido para null uma coleo vazia.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-36
Injeo entre beans colaboradores

No Spring so chamados de beans colaboradores todo objeto que criado por
voc, como por exemplo, um objeto de negcio e que deve ser injetado em outro
objeto, em sntese o ato de injetar um pojo em outro. No existe nada de mgico
nisso, alm de simples muito usual, talvez a funcionalidade mais simples do
container IoC do Spring, porm a mais utilizada junto com as injees por setter. A
injeo de colaboradores feita atravs de setters ou construtor como as outras
injees vistas anteriormente.

package com.targettrust.spring.colaboradores;

public class Cidade {

private String nome;

public Cidade() {}

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

@Override
public String toString() {
return nome;
}

}
Cdigo 2.28 Cidade.java Classe colaboradora.

package com.targettrust.spring.colaboradores;

import java.util.List;

public class Estado {

private String sigla;
private List<Cidade> cidades;

public Estado() {}

public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-37
public List<Cidade> getCidades() {
return cidades;
}
public void setCidades(List<Cidade> cidades) {
this.cidades = cidades;
}

@Override
public String toString() {
return sigla + " cidades: " + cidades;
}
}

Cdigo 2.28 Estado.java Classe que utiliza a colaboradora.
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="cidA"
class="com.targettrust.spring.colaboradores.Cidade"

>
<property name="nome"><value>Porto Alegre</value></property>
</bean>

<bean
id="cidB"
class="com.targettrust.spring.colaboradores.Cidade"

>
<property name="nome"><value>Gravata</value></property>
</bean>

<bean
id="estado"
class="com.targettrust.spring.colaboradores.Estado"

>
<property name="sigla" value="RS" />
<property name="cidades">
<list>
<ref bean="cidA" />
<ref local="cidB" />
<bean
class="com.targettrust.spring.colaboradores.Cidade">
<property name="nome" value="Canoas" />
</bean>
</list>
</property>
</bean>

</beans>
Cdigo XML 2.15 Injees de colaboradores.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-39
Nesse exemplo foi injetado uma java.util.List de Cidades no objeto Estado.
Podemos reutilizar injees com a tag ref. Quando usamos ref com bean estamos
criando a possibilidade de acessar qualquer bean do contexto do Spring em qualquer
XML de configurao. Quando utilizado o atributo local s podemos utilizar os beans
que esto no mesmo XML, se o bean em questo estiver em outro XML, um erro ser
levantado. Podemos ver o resultado dessas classes em ao no teste abaixo:

package com.targettrust.spring.colaboradores;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestColaboradores {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/colaboradores/Spri
ng-beans.xml");
System.out.println(bf.getBean("estado"));
}
}
Cdigo 2.29 TestColaboradores.java Teste de colaboradores.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-40
Instanciando o contexto Web
O Spring tem uma factory especfica para a utilizao do framework em
ambiente servlet/JEE. possvel utilizar o listener
org.springframework.web.context.ContextLoaderListener ou o Servlet
org.springframework.web.context.ContextLoaderServlet.
Basta configurar isso no web.xml de sua aplicao, conforme exemplo abaixo:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/Spring-beans.xml
</param-value>
</context-param>

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

<!-- ou use o ContextLoaderServlet ou invs de usar o listener
acima.
<servlet>
<servlet-name>context</servlet-name>
<servlet-
class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
-->

</web-app>
Cdigo XML 2.16 web.xml.
Agora s criar um bean no Spring para podermos utilizar esse contexto web.
Nesse exemplo ser criado o DateService que um service que ir prover a data
atual. Observe o cdigo abaixo:
package com.targettrust.spring.web;

public class DateService {
public String getDate(){
System.out.println("Provendo servio de data");
return new java.util.Date().toString();
}
}
Cdigo 2.23 DateService.java.

Agora necessrio fazer as configuraes desse bean no contexto do Spring,
confira isso no XML abaixo:
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dateService"
class="com.targettrust.spring.web.DateService"

/>

</beans>
Cdigo XML 2.17 Spring-beans.xml.

Para testar, vamos empacotar essa aplicao em um arquivo war. Para fazer
esse teste vamos chamar o servio do Spring atravs de uma pgina jsp. Confira o
cdigo abaixo:

<%@page language="java" contentType="text/html; charset=ISO-8859-1"%>
<%@page
import="org.springframework.web.context.support.WebApplicationContextUtils
"%>
<%@page import="com.targettrust.spring.web.DateService"%>

<html>
<title>Spring WEB</title>
<body>
<center><h2>Exemplo de Spring com WEB-Tier</h2></center><br>
A Data atual :
<%=((DateService)WebApplicationContextUtils.getWebApplicationContext(getSe
rvletConfig().getServletContext()).getBean("dateService")).getDate()%>

</body>
</html>
Cdigo 2.23 index.jsp.

usado um utilitrio do Spring para acessar o contexto dele atravs de uma
pgina jsp. Atravs da classe org.springframework.web.context.
support.WebApplicationContextUtils ns obtemos o contexto do Spring. Utilizamos o
mtodo getWebApplicationContext passando como parmetro o ServletContext.
Spring Framework Framework para desenvolvimento de aplicaes java

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

1. Faa a injeo de um objeto Cliente em um Objeto Vendedor.
2. Faa a injeo de uma Lista de Alunos em um Objeto Turma.
3. Faa a injeo de um Mapa de UF com uma Lista de Cidades.
4. Faa a injeo de um UF em um objeto Pas atravs de constructor injection.
5. Faa um Servio de Calculadora e injete funes matemticas nesse bean.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 2-43
Espao para anotaes

Spring Framework Framework para Desenvolvimento de Aplicaes Java

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


M
M
a
a
n
n
i
i
p
p
u
u
l
l
a
a

o
o
d
d
e
e
B
B
e
e
a
a
n
n
s
s


Spring Framework Framework para desenvolvimento de aplicaes java

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

Conhecer os Resource Loaders do Spring;
Saber utilizar o init-method;
Saber utilizar a herana de definies de beans;
Saber fazer classes de validaes;
Saber utilizar Bean Wrapper;
Conhecer os PostProcessors do Spring;
Conhecer os principais property editors;
Conhecer os Eventos do container;
Saber utilizar o PropertyPlaceholderConfigurer;
Saber utilizar SingletonBeanFactoryLocator;
Conhecer os recursos de Internacionalizao.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Quando usamos arquivos de configuraes como, por exemplo, xml, txt,
arquivos de imagem, properties, etc fortemente recomendado o uso de
ResourceLoader que uma interface do Spring que define a estratgia para
carregar arquivos. O Spring prove uma especializao dessa interface que a classe
ResourcePatternResolver que adiciona facilidades como patterns de estilo ant,
podemos usar wild cards como, por exemplo: WEB-INF/*-context.xml. Podemos
utilizar a classe ServletContextResourceLoader que faz a busca de recursos no
ServletContext. As BeanFactorys do Spring como, por exemplo:
ClassPathXmlApplicationContext implementa ResourceLoader atravs de classes
em sua hierarquia superior. Em sntese, as outras Beans factories do Spring tambm
implementam essa interface ResourceLoader.
Considerando a injeo do seguinte bean.

<property name="arquivo" value="classpath:caminho/completo/dados.txt">
Cdigo XML 3.1 injeo de resource
Nesse cdigo XML acima utilizando um facilitador o classpath: atravs dessa
diretiva, instrumos o ResourceLoader a carregar esse arquivo que esteja em
qualquer lugar no classpath. Poderamos utilizar o facilitador file: para carregar
arquivos que no esto no classpath da aplicao. Exemplo:

<property name="arquivo" value="file:/dados/caminho/completo/da dos.txt">
Cdigo XML 3.2 injeo de resource fora do classpath
Esse facilitador tambm pode ser utilizado para carregar arquivos que esto
no classpath, mas para esse caso mais recomendado o uso de classpath:. Nesse
tipo de cenrio se utiliza file: quando existem mais de um arquivo com o mesmo
nome.


Podemos utilizar wild cards no stilo ant, segue alguns exemplos:

/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
Cdigo de exemplos wild cards

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-4
Init-Metohd e InitializingBean
O Spring prove alguns mecanismos de call back aps a inicializao de um
bean. Aps o container de IoC do Spring resolver as injees de dependncias ele
prove um Call Back, ou seja, ele pode estar invocando um mtodo em sua classe e a
partir desse mtodo voc realiza algum processamento. Essa operao pode ser
configurada atravs da propriedade init-method. Essa soluo elegante, pois no
gera acoplamento entre o cdigo do Spring e seu cdigo. Veja isso na prtica no
exemplo abaixo:

package com.targettrust.spring.init;

import java.util.Date;

public class HoraCertaService {

private Date data;
private String pais;

public HoraCertaService() {
System.out.println("Criando Bean de HoraCertaService ");
}

public void preparar(){
data = new Date();
System.out.println("Ajustado a hora para o pais: " + pais);
}

@SuppressWarnings("deprecation")
public String getHoraCerta(){
return pais + " -> " + data.getHours() + ":" +
data.getMinutes() + ":" + data.getSeconds();
}


public void setPais(String pais) {
this.pais = pais;
}
}
Cdigo 3.1 HoraCertaService.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="horaCertaService"
class="com.targettrust.spring.init.HoraCertaService"
init-method="preparar"
>
<property name="pais" value="Brasil" />
</bean>

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-5
</beans>
Cdigo XML 3.2 injeo com uso de init-method

package com.targettrust.spring.init;

import org.springframework.beans.factory.BeanFactory;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/init/Spring-
beans.xml");

HoraCertaService bean =
(HoraCertaService)bf.getBean("horaCertaService");
System.out.println("Hora: " + bean.getHoraCerta());

}
}
Cdigo 3.2 Testjava








Existem outras formas de utilizar Call back no Spring, porm menos
elegantes, pois acoplam o cdigo do Spring com o de sua aplicao. Uma
possibilidade seria utilizar a interface org.springframework.beans.
factory.InitializingBean essa interface possui o mtodo afterPropertiesSet(). Esse
mtodo invocado pela BeanFactory do Spring aps todas as dependncias serem
resolvidas.

Assim como existe a propriedade init-method existe a propriedade destroy-
method que um Call Back para quando o container destrudo. possvel utilizar
uma interface para esse Call Back, a interface
org.springframework.beans.factory. DisposableBean essa interface contm o
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-6
mtodo destroy(). Esse mtodo ser invocado no momento da destruio do
contexto do Spring.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-7
Herana de Definies

Em uma aplicao orientada a objetos utilizamos com freqncia os recursos
de herana, a partir de um objeto pai nasce um objeto filho que herda os mtodos
e propriedades de seu pai. O Spring framework prove mecanismos para herana de
injees. Considere o seguinte Service:

package com.targettrust.spring.extend;

public abstract class PessoaService {

private String nome;
private String telefone;
private String email;

public PessoaService() {}

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

public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}

public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Cdigo 3.3 PessoaService.java

Essa uma Service (Classe de regra de negcios) que representa operao
sobre uma pessoa, aqui temos um exemplo simplrio, no usual ter propriedades
como nome e telefone em um Service, normalmente se utiliza isso em pojos. Mas
como exemplo de herana de definies valido.

package com.targettrust.spring.extend;

public class PessoaFisicaService extends PessoaService {

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-8
private String cpf;

public PessoaFisicaService() {}

public boolean validaCpf(){
return CpfUtils.validaCPF(cpf);
}

public void mostraPessoa(){
if (validaCpf()){
System.out.println("nome: " + getNome() +
" telefone: " + getTelefone() +
" email: " + getEmail() +
" cpf: " + cpf);
}else{
System.out.println("Essa pessoa no tem um CPF
Valido.");
}

}

public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
}

Cdigo 3.4 PessoaFisicaService.java

Em PessoaFisicaService adicionamos a propriedade cpf e mtodos como
validaCpf e mostra pessoa, que ira mostrar a pessoa com seus dados caso o cpf seja
vlido. Foi utilizada a classe CpfUtils para fazer a validao do CPF, voc pode
verificar os fontes no projeto do eclipse que acompanha a apostila.

Para fazer a herana de definies no Spring necessrio existir uma
estrutura de herana. Utilizamos as propriedades abstract e parent para fazer a
herana. Veja isso na prtica no XML de configuraes seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="pessoaService"
class="com.targettrust.spring.extend.PessoaService"
abstract="true"
>
<property name="nome" value="Diego" />
<property name="email"
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-9
value="pacheco@diego.com.spring" />
<property name="telefone" value="455-55-55" />
</bean>

<bean
abstract="false"
id="pessoaFisicaService"
class="com.targettrust.spring.extend.PessoaFisicaService"
parent="pessoaService"
>
<property name="cpf" value="47888971210" />
</bean>

</beans>
Cdigo XML 3.3 injeo com uso de herana.

Para testar podemos utilizar a classe de testes a baixo:

package com.targettrust.spring.extend;

import org.springframework.beans.factory.BeanFactory;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Teste {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/extend/Spring-
beans.xml");

PessoaFisicaService bean =
(PessoaFisicaService)bf.getBean("pessoaFisicaService");
bean.mostraPessoa();
}

}
Cdigo 3.5 Teste.java

OBS: o atributo abstract=true apenas uma demarcao no Spring e no
obrigatorio que sua classe seja abstrata.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Em uma aplicao ter injees de dependncias pode no ser suficiente,
necessrio validar. O spring prove mecanismos de validao atravs da interface
org.springframework.validation. Validator. Essa interface trabalha com um
objeto de erro e podemos ver um relatrio de erros posteriormente. Essa interface
pode ser usada em conjunto com um outro framework do portiflio do Spring, o
Spring MVC, atravs de uma tag, pode mostrar os erros de validao de forma
elegante em uma pagina JSP. A Interface Validator tem os seguintes mtodos:
boolean supports(Class clazz);
void validate(Object target, Errors errors);
No mtodo supports deve-se retornar true se o validador que estamos
construindo tem suporte para o Class passado por parmetro. Normalmente se faz
um equals aqui com o parmetro e a classe que o validador ser responsvel.
O mtodo validate ir validar os dados de fato, caso seja necessrio retornar
error, isso ser feito atravs do objeto de errors. Veja o exemplo prtico a seguir:

package com.targettrust.spring.validate;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class Pessoa implements Validator{

private String nome;
private Integer idade;

public Pessoa() {}

@Override
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return Pessoa.class.equals(clazz);
}

@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "nome", "nome.vazio");
Pessoa p = (Pessoa) target;
if (p.getIdade() < 0) {
errors.rejectValue("idade", "valor negativo");
} else if (p.getIdade() > 120) {
errors.rejectValue("idade", "velho demais");
}
}

public String getNome() {
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-11
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}

public Integer getIdade() {
return idade;
}
public void setIdade(Integer idade) {
this.idade = idade;
}

}
Cdigo 3.6 Pessoa.java e classe de validao

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="pessoa"
class="com.targettrust.spring.validate.Pessoa"

>
<property name="nome" value="Fulano" />
<property name="idade" value="-1" />
</bean>

</beans>
Cdigo XML 3.4 injeo com uso de validator

package com.targettrust.spring.validate;

import org.springframework.beans.factory.BeanFactory;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;

public class Teste {
public static void main(String[] args) {

BeanFactory bf = new ClassPathXmlApplicationContext(

"/com/targettrust/spring/validate/Spring-beans.xml");

Pessoa p = (Pessoa) bf.getBean("pessoa");
System.out.println("Nome: " + p.getNome() + " idade: " +
p.getIdade());

Errors e = new BeanPropertyBindingResult(p,"Pessoa");
p.validate(p, e);

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-12
for(Object es: e.getAllErrors()){
System.out.println(es);
}

}
}
Cdigo 3.7 Teste.java

Nesse exemplo, a partir de uma classe Pessoa foi construdo um Validator
para validar o objeto. Esse validator est na mesma classe Pessoa, seria possvel
colar esse cdigo de validao em outra classe tambm.
Foi utilizado uma classe utilitria do Spring que a ValidateUtils que j tem alguns
mtodos que facilitam a validao.
Para o teste foi instanciado um objeto de Erro e passado esse objeto para o
mtodo de validao, e no final foi iterado todos os erros e mostrado no console as
mensagens de erros. Nos prximos captulos essa questo ser abordada com outra
roupagem na questo dos interceptors do Spring.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-13
Bean Wrapper

Bean Wrapper um recurso do Spring que funciona com Java beans como o
prprio nome j diz, Java beans um especificao da Sun que define se um
determinado objeto deve ter um construtor vazio e mtodos getters e setters de
acordo com o padro da Sun camelCase. Essa funcionalidade na verdade um
pattern do GOF que se chama decorator. Que tambem conhecido como Wrapper
que significa empacotar, no caso ns temos uma camada de adiciona um
funcionalidade adicional a algo existente.

BeanWrapper uma interface do Spring que prove funcionalidades de get e
set em propriedades e propriedades de consulta que podem determinar se a
propriedade pode ser escrita ou lida. Tambm possibilita setar propriedades e sub-
propriedades de uma profundidade ilimitada. Outra funcionalidade adicionar
listeners para quando alguma propriedade mudar de valor.

Esse recurso pode ser utilizado para fazer manipulaes com propriedades
de objetos de maneira elegante. Tambm usual para fazer algum tipo de bind em
sua aplicao. Confira como codificar abaixo:

package com.targettrust.spring.beanwrapper;

public class Funcionario {

private String nome;
private Long salario;

public Funcionario() {}

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

public Long getSalario() {
return salario;
}
public void setSalario(Long salario) {
this.salario = salario;
}

@Override
public String toString() {
return "Funcionario[ nome: " + nome +
" , salario: " + salario + " ]";
Spring Framework Framework para desenvolvimento de aplicaes java

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

}
Cdigo 3.8 Funcionario.java

package com.targettrust.spring.beanwrapper;

public class Empresa {

private String nome;
private Funcionario gestor;

public Empresa() {}

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

public Funcionario getGestor() {
return gestor;
}
public void setGestor(Funcionario gestor) {
this.gestor = gestor;
}

@Override
public String toString() {
return "Empresa [ " + nome + " | " + gestor.toString() + "
]";
}
}
Cdigo 3.9 Empresa.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="gestor"
class="com.targettrust.spring.beanwrapper.Funcionario"

>
<property name="nome" value="Joo" />
<property name="salario" value="100" />
</bean>

<bean
id="empresa"
class="com.targettrust.spring.beanwrapper.Empresa"

>
<property name="nome" value="CromFactory" />
<property name="gestor" ref="gestor" />
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-15
</bean>
</beans>
Cdigo XML 3.5

package com.targettrust.spring.beanwrapper;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanFactory;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Teste {

public static void main(String[] args) {
BeanFactory bf =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/beanwrapper/Sprin
g-beans.xml");

System.out.println(bf.getBean("empresa"));

BeanWrapper company = new
BeanWrapperImpl((Empresa)bf.getBean("empresa"));
company.setPropertyValue("nome", "Target Trust");

// ou pode ser algo assim
PropertyValue value = new PropertyValue("nome", "Some Company
Inc.");
company.setPropertyValue(value);

BeanWrapper diego = new
BeanWrapperImpl((Funcionario)bf.getBean("gestor"));
diego.setPropertyValue("nome", "Diego Pacheco");

company.setPropertyValue("gestor",
diego.getWrappedInstance());

Long sal = (Long) company.getPropertyValue("gestor.salario");

System.out.println("Salrio: " + sal);

System.out.println(company);
System.out.println(company.getWrappedInstance());

// verifica o tipo da propriedade salario

System.out.println(((BeanWrapperImpl)company).getPropertyDescriptor
("gestor.salario").getPropertyType());

diego.setPropertyValue("salario",200L);
System.out.println(diego.getPropertyValue("salario"));
}
}
Cdigo 3.10 Teste.java

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-16
No exemplo acima criado uma instncia de BeanWrapperImpl a partir do
bean empresa e outra BeanWrapperImpl a partir do bean gestor. Com os mtodos
getPropertyValue e setPropertyValue podemos modificar os valores dos objetos.
Para acessar objeto real utilizamos o mtodo getWrappedInstance. Outra maneira
de acessar as propriedades do objeto atravs do objeto PropertyValue, porm
ainda precisamos de uma instncia de BeanWrapper.

As propriedades desse objeto podem ser acessadas com infinita
profundidade, por exemplo: supondo que temos um objeto Pessoa que tem um
objeto Brinquedo que tem uma propriedade tamanho, poderamos acessar essa
propriedade da seguinte maneira:
beanWrapperInstancePessoa.getPropertyValue("brinquedo.tamanho"), supondo que
temos uma instncia de BeanWrapper com a varivel beanWrapperInstancePessoa.
Outros exemplos de acesso com propriedades:

Expresso Descrio
nome Corressponde a propriedade nome do objeto empacotado, ir
tentar executar um getNome() ou isNome()
conta.valor Indica que no objeto corrente existe uma propriedade conta
que tem uma propriedade valor, executa algo como:
getConta().getValor()
filhos[2] Acessa a segunda posio da propriedade filhos sendo que
filhos pode ser um array ou List ou qualquer outra collection
ordenada.
estado[poa] Indica que est sendo acessado a entrada poa em uma Map
chamado estado.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Esse um recurso para customizar beans atravs de call-backs. Que nada
mais so do que mtodos a serem invocados aps determinada operao ser
executada, tambm conhecidos na literatura computacional como ganchos. Voc
pode utilizar esse recurso para estender as operaes padro do Spring para: lgica
de instanciao, lgica de resoluo de dependncias e tambm se necessrio para
operaes aps o container do Spring finalizar suas criaes de objetos. Voc pode
configurar mltiplos BeanPostProcessors se desejar assim, possvel configurar a
ordem que cada um ir rodar a partir da propriedade order, mas isso s ser possvel
se voc implementar a interface Ordered. Existe uma forte recomendao por parte
dos criadores do Spring que voc faa essa implementao.
A atuao do BeanPostProcessors aps a criao do bean do Spring, se
desejarmos mudar sua definio necessrio utilizar BeanFactoryPostProcessor que
ser abordado no prximo tpico.
Aps cada criao de um bean no container o Spring estar invocando o
BeanPostProcessor, isso significa que ser executado antes de qualquer mtodo init-
bean.
Existe uma diferena de se usar BeanPostProcessor com BeanFactory e com
ApplicationContext, por que no caso da ApplicationContex o Spring ir descobrir
todos os BeanPostProcessors e registrar automaticamente para voc, j em outra
linha, a Bean Factory no far nada disso, devemos registr-los manualmente.
Conforme o cdigo abaixo:

ConfigurableBeanFactory factory = new XmlBeanFactory(new
ClassPathResource("beans.xml"));

MeuBeanPostProcessor postProcessor = new MeuBeanPostProcessor();
factory.addBeanPostProcessor(postProcessor);
Cdigo 3.11 Exemplo de registro de BeanPostProcessor.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-18
Esse tipo de Registro no conveniente, por causa disso que para muitas
aplicaes as pessoas preferem utilizar ApplicationContex ao invs de BeanFactory.
Classes que implementam BeanPostProcessor so classes especiais, logo so
tratadas de maneira diferente pelo container. Todas as BenPostProcessors e aqueles
beans que estejam diretamente referenciados por eles sero instanciados ao startup
do Spring.
Os recursos de AOP auto-proxing so implementados como
BeanPostProcessor, nenhum BeanPostProcessor ou beans diretamente
referenciados sero elegveis para auto-proxy, ou seja, no haver aspectos sobre
eles. O Spring ir lhe alertar sobre essa situao com uma mensagem semelhante a
essa: Bean 'foo' is not eligible for getting processed by all BeanPostProcessors (for
example: not eligible for auto-proxying). Veja um exemplo prtico de como utilizar
este recurso:

package com.targettrust.spring.beanpostprocessors;

public class ObjetoA {

}
Cdigo 3.12 ObjetoA.java

package com.targettrust.spring.beanpostprocessors;

public class ObjetoB {

}
Cdigo 3.13 ObjetoB.java

package com.targettrust.spring.beanpostprocessors;

public class ObjetoC {

}
Cdigo 3.14 ObjetoC.java

Spring Framework Framework para desenvolvimento de aplicaes java

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


package com.targettrust.spring.beanpostprocessors;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class LogCreationBeanPostProcessor implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String
beanName)
throws BeansException {
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String
beanName)
throws BeansException {
System.out.println("Craindo bean: " + beanName);
return bean;
}
}
Cdigo 3.15 LogCreationBeanPostProcessor.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="false"
>
<bean
id="a"
class="com.targettrust.spring.beanpostprocessors.ObjetoA"
/>
<bean
id="b"
class="com.targettrust.spring.beanpostprocessors.ObjetoB"
/>
<bean
id="c"
class="com.targettrust.spring.beanpostprocessors.ObjetoC"
/>
<bean
class="com.targettrust.spring.beanpostprocessors.LogCreationBeanPostProce
ssor"
/>
</beans>
Cdigo XML 3.6 Xml de configuraes
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.beanpostprocessors;

import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class Teste {
public static void main(String[] args) {
new
ClassPathXmlApplicationContext("/com/targettrust/spring/beanpostprocessor
s/Spring-beans.xml");
}
}
Cdigo 3.16 Teste.java

A interface BeanPostProcessor possui dois mtodos, so eles:
postProcessBeforeInitialization
postProcessAfterInitialization

Um dos mtodos serve para efetuar operaes antes da inicializao e outro
aps a inicializao do bean no contexto do Spring. Ambos os mtodos recebem o
objeto e seu nome por parmetro, assim podemos aplicar algum proxy ou regra de
negcio. Aqui poderamos utilizar um Validator conforme visto nos tpicos
anteriores e forar a validao de determinadas propriedades.
Outra possibilidade que temos aqui graas a esse extraordinrio recurso do Spring
que podemos criar annotations personalizadas ou fazer os componentes
implementarem interfaces e com esse gancho do BeanPostProcessor podemos ler
essas informaes e efetuar diversas operaes que nos desperte interesse.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-21
BeanFactoryPostProcessors
Similar ao BeanPostProcessor, porm o BeanFactoryPostProcessor consegue
ler os metadados de configurao do Spring e tambm mudar esses dados antes
que o Spring crie seus beans. Voc pode configurar muitos
BenFactoryPostProcessor. possvel configurar a ordem de execuo dessa classe
implementando a interface Ordered. Se voc deseja mudar a instncia de um bean
j criado voc deve utilizar o BeanPostProcessor conforme apresentando no tpico
anterior. O Prprio Spring utiliza beanFactoryPostProcessor como:
PropertyResourceConfigurer e PropertyPlaceholderConfigurer.
Se estamos utilizando ApplicationContext o registro feito de forma
automtica, se estivermos utilizando uma BeanFactory precisamos fazer isso de
forma manual. A Forma de fazer isso est exemplificada logo abaixo:

XmlBeanFactory factory = new XmlBeanFactory(new
FileSystemResource("beans.xml"));

PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));

cfg.postProcessBeanFactory(factory);
Cdigo 3.17 Exemplo de registro de BeanPostProcessor.

No cdigo acima criando um PropertyPlaceHolderConfigurer que uma
implementao de BeanFactoryPostProcessor e ser detalhada nos prximos
tpicos.
Veja agora um exemplo concreto de como poderia ser utilizado o
BeanFactoryPostProcessor:

package com.targettrust.spring.beanfactorypostprocessors;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DataService {

private String pattern;

public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}

public String showSysDate(){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(new Date());
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-22
}
}
Cdigo 3.18 DataService.java

package com.targettrust.spring.beanfactorypostprocessors;

import java.io.FileInputStream;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;

import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class DatePatternRouterBeanFactoryPostProcessor implements
BeanFactoryPostProcessor {

@Override
@SuppressWarnings("unchecked")
public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {

Properties p = new Properties();
try {
p.load(new
FileInputStream("./src/com/targettrust/spring/beanfactorypostprocessors/p
atterns.properties"));
System.out.println("Patterns: " + p);
} catch (Exception e) {
throw new FatalBeanException("Erro ao buscar
patterns!",e);
}

Map<Object,Object> beans =
beanFactory.getBeansOfType(DataService.class);
for(Entry<Object, Object> e: beans.entrySet()){
System.out.println("Aplicando pattern em service: " +
e);
DataService service = ((DataService)e.getValue());
service.setPattern(p.getProperty("pattern." +
service.getPattern().replace("#", "")));
}
}
}
Cdigo 3.19 DatePatternRouterBeanFactoryPostProcessor.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="false"
>
<bean
id="brasilDateService"

class="com.targettrust.spring.beanfactorypostprocessors.DataService"

>
<property name="pattern" value="#brasil" />
</bean>

<bean
id="usDateService"

class="com.targettrust.spring.beanfactorypostprocessors.DataService"

>
<property name="pattern" value="#us" />
</bean>

<bean

class="com.targettrust.spring.beanfactorypostprocessors.DatePatternR
outerBeanFactoryPostProcessor" />

</beans>
Cdigo XML 3.7 Xml de configuraes

package com.targettrust.spring.beanfactorypostprocessors;

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

public class Teste {
public static void main(String[] args) {
ApplicationContext ap = new
ClassPathXmlApplicationContext("/com/targettrust/spring/beanfactorypostpro
cessors/Spring-beans.xml");
System.out.println("Data Brasil pattern : " +
((DataService)ap.getBean("brasilDateService")).showSysDate());
System.out.println("Data Us pattern : " +
((DataService)ap.getBean("usDateService")).showSysDate());
}
}
Cdigo 3.20 Teste.java
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-24
A Interface BeanFactoryPostProcessor s tem um mtodo:
postProcessBeanFactory
Que recebe por parmetro um ConfigurableListableBeanFactory que a bean
factory que est sendo configurada.Com esse parmetro podemos manipular as
informaes da BeanFactory.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-25
Property Editors

Esse recurso utilizado largamente no Spring framework. Property Editors
tm a capacidade de converter informaes em seus tipos de dados corretos, por
exemplo, imagine que gostaramos de injetar um uma propriedade do tipo File em
um bean do Spring para tal necessidade teriamos de fazer o seguinte
procedimento:
<bean
id="txt"
class="java.io.File"
>
<constructor-arg index="0" value="C:/BOOTSECT.BAK" />
</bean>
Cdigo XML 3.8 Injeo de File

Aps isso seria possvel injetar esse bean txt no bean que necessita de um
File. Porm isso muito doloroso e nada produtivo. No seria mais fcil se o Spring
detectar-se automaticamente uma propriedade de um bean que um File e criasse
o File para ns? O Spring j faz isso para ns se injetarmos um caminho para uma
File ele automaticamente faz isso para ns, por que ele j tem um PropertyEditor
default que est registrado para tal trabalho. Esse Property Editor default chama-se
FileEditor. Confira os PropertyEditor disponveis no Spring:
Property Editor Explicao
ByteArrayPropertyEditor Editor para arrays de bytes. Strings vo ser convertidas
em suas correspondentes representaes de bytes.
ClassEditor Faz parte de String representando classes. Quando a
classe no encontrada levantado um
IllegalArgumentException. No registrado por default.
CustomBooleanEditor Esse property editor para propriedades booleans.
Trabalha com os valores [ true, false, on, off, yes, no, 0,
1]

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-26
CustomCollectionEditor Editor para qualquer tipo de coleo, til quando
precisamos alguma coleo especifica.
CustomDateEditor Editor para java.util.Date esse editor no est registrado
por default. Precisa ser registrado com um formato de
data especifico.
CustomNumberEditor Editor para qualquer subclass de Number como por
exemplo: Integer, Long, Float, Double. registrado por
default.
FileEditor Capaz de criar arquivos do tipo java.io.File e
registrado por default.
InputStreamEditor Atravs do ResouerceDitor e Resource pode instanciar
um InputStream, mas o Spring no ir fechar o Stream
para voc, utilizado por default.
LocaleEditor Capaz de materializar objetos do tipo Locale, a partir de
uma String no formato ling_pais. Registrado por default
PatternEditor Resolve String para o Objeto Pattern, conforme jdk 1.5.
PropertiesEditor Converte Strings em objetos java.lang.Properties.
registrado por default.
StringTrimmerEditor

Property Editor que aplica um trim nas Strings,
opcionalmente pode transformar uma String vazia em
null. No registrado por default.
URLEditor Capaz de converter uma String em um objeto URL.
Registrado por default.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-27
O Springframework utiliza java.beans.PropertyEditorManager para gerenciar
e procurar os property editor que so necessrios a ele. Esse path de procura tem
tambm sun.bean.editors que conta com editores como: Font, Color e a maioria
dos tipos primitivos.
A Implementao padro dos javabeans da Sun ir automaticamente
descobrir property editor para voc, mesmo que no tenha ocorrido um registro
prvio. Mas isso s ir ocorrer se o seu Property Editor estiver na mesma package
que o tipo que ele cobre e tendo o mesmo nome da Classe + o sufixo Editor.
Exemplo:
com
chank
pop
Foo
FooEditor // PropertyEditor para a Classe Foo

Voc pode criar seu prprio Property Editor, para isso voc precisar
estender a classe PropertyEditorSupport e registrar esse custom editor criado por
voc no XML do Spring. Veja o exemplo a seguir:
package com.targettrust.spring.propertyeditor;

public class Aluno {

private String nome;

public Aluno() {}

public Aluno(String nome) {
super();
this.nome = nome;
}

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

@Override
public String toString() {
return nome;
}

}
Cdigo 3.21 Aluno.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.propertyeditor;

import java.util.List;

public class Turma {

private String nome;
private List<Aluno> alunos;

public Turma() {}

public Turma(String nome, List<Aluno> alunos) {
super();
this.nome = nome;
this.alunos = alunos;
}

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

public List<Aluno> getAlunos() {
return alunos;
}
public void setAlunos(List<Aluno> alunos) {
this.alunos = alunos;
}

@Override
public String toString() {
return nome + " alunos: " + alunos.toString();
}

}
Cdigo 3.22 Turma.java

package com.targettrust.spring.propertyeditor;

import java.beans.PropertyEditorSupport;

public class AlunoEditor extends PropertyEditorSupport{
@Override
public void setAsText(String text) throws IllegalArgumentException
{
Aluno a = new Aluno(text);
setValue(a);
}
}
Cdigo 3.23 AlunoEditor.java

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-29
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="turma"
class="com.targettrust.spring.propertyeditor.Turma">
<property name="nome" value="Curso-Spring" />
<property name="alunos">
<list>
<value>Rod</value>
<value>Joe</value>
<value>Bart</value>
<value>Homer</value>
<value>Hammer</value>
</list>
</property>
</bean>

<bean id="customEditorConfigurer"

class="org.springframework.beans.factory.config.CustomEditorConfigu
rer">
<property name="customEditors">
<map>
<entry
key="com.targettrust.spring.propertyeditor.Aluno">
<bean
class="com.targettrust.spring.propertyeditor.AlunoEditor" />
</entry>
</map>
</property>
</bean>

</beans>
Cdigo XML 3.9 Registro do property editor

Com os property editors a injeo de propriedades fica muito mais simples e
mais rpida de ser efetuada. Nesse exemplo, como o pojo Aluno est no mesmo
package do seu Editor possivel apagar o bean customEditorCon- figurer, porque o
mecanismo padro da Sun de java beans ir detectar para ns.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-30
Eventos
A escuta de eventos em um objeto ApplicationContext feita atravs dos
objetos ApplicationEvent e ApplicationListener. Se um bean implementa a interface
ApplicationListener publicado no contexto do Spring toda vez que for publicado
um evento do tipo ApplicationEvent o seu bean vai ser notificado. Confira alguns
dos eventos disponveis por padro na ApplicationContext.
Evento Descrio
ContextRefreshedEvent Publicado quando a ApplicationContext inicializado
ou atualizado, isso significa quando todos os beans
foram carregados e o Spring est pronto para ser
usado(container IoC)
ContextClosedEvent Publicado quando a ApplicationContext fechada,
usando o mtodo close.
RequestHandleEvent Um evento Especfico da Web referente a uma
requisio HTTP, evento publicado aps a requisio
HTTP se finalizar. Esse evento s pode ser utilizado para
aplicaes Web que utilizam o DispatcherServlet do
Spring.

Os eventos no Spring so resolvidos de forma sncrona, ou seja, o Spring ir
bloquear at que todos os listeners tenham terminado suas operaes. Veja como
criar um evento personalizado em sua aplicao:
package com.targettrust.spring.event;

import org.springframework.context.ApplicationEvent;

public class FeriadoEvent extends ApplicationEvent{

private String data;

private static final long serialVersionUID = 1L;

public FeriadoEvent(Object source,String data) {
super(source);
this.data = data;
}

public String getData() {
return data;
}

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-31
}
Cdigo 3.24 FeriadoEvent.java

package com.targettrust.spring.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class FeriadoListener implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof FeriadoEvent){
FeriadoEvent fe = (FeriadoEvent)event;
System.out.println("Viva! Dia: " + fe.getData() + "
feriado. Uhhuu!!!" );
}
}
}
Cdigo 3.25 FeriadoListener.java

package com.targettrust.spring.event;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class RH implements ApplicationContextAware {

private ApplicationContext ac;

public void pulicarFeriados(){
ac.publishEvent(new FeriadoEvent(this,"01/01/08"));
}

@Override
public void setApplicationContext(ApplicationContext
applicationContext)
throws BeansException {
ac = applicationContext;
}
}
Cdigo 3.26 RH.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="rh"
class="com.targettrust.spring.event.RH"

/>

<bean
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-32
id="funcionarioEsperto"
class="com.targettrust.spring.event.FeriadoListener"
/>

</beans>
Cdigo XML 3.10 Registro do listener

package com.targettrust.spring.event;

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

public class Teste {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/event/Spring-
beans.xml");

RH rh = (RH)ac.getBean("rh");
rh.pulicarFeriados();
}
}
Cdigo 3.27 Teste.java

Nesse exemplo foi utilizado o FeridoEvent que uma classe que estende
ApplicationEvent do Spring. Para tratar o evento foi criada a classe FeriadoListener
que implementa ApplicationListener com um if parta saber se o evento disparado foi
o FeriadoEvent. A Classe RH uma ApplicationContextAware para poder publicar o
evento atravs do mtodo publishEvent.
Spring Framework Framework para desenvolvimento de aplicaes java

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

PropertyPlaceHolderConfigurer uma forma de externalizar informao na
bean factory. Esse objeto implementa BeanFactoryPostProcessor para poder efetuar
suas modificaes nos metadados do Spring. A vantagem que podemos
externalizar nossas configuraes em arquivos.proprerties e o Spring ir buscar
nesses arquivos as configuraes. Muito til para informaes de ambientes como
conexes de bancos de dados, usurios, senhas e listas de e-mails, com a vantagem
de no precisar mexer no XML de definies do Spring, reduzindo assim o risco de
outros possveis erros. possvel procurar tambm nas propriedades do sistema,
para isso necessrio setar o modo systemPropertiesMode.
Pode ser utilizado para substituir classes, por exemplo, podemos fazer uma
lgica que escolhe em tempo de runtime qual classe ser utilizada para um
determinado bean, muito til para fazer determinados roteamentos, para esse tipo
de situao til utilizar o escopo de prototype.
Para utilizar o PropertyPlaceHolderConfigurer necessrio registr-lo no
Spring e informar a localizao dos arquivos properties. Veja um exemplo concreto
abaixo:

package com.targettrust.spring.propertyplaceholderconfigurer;

public class Instrutor {

private String nome;
private int idade;
private String time;
private float altura;

public Instrutor() {}

public Instrutor(String nome, int idade, String time, float altura)
{
super();
this.nome = nome;
this.idade = idade;
this.time = time;
this.altura = altura;
}

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

public int getIdade() {
return idade;
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-34
}
public void setIdade(int idade) {
this.idade = idade;
}

public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}

public float getAltura() {
return altura;
}
public void setAltura(float altura) {
this.altura = altura;
}

@Override
public String toString() {
return " nome: " + nome +
" idade: " + idade +
" altura : " + altura+
" time: " + time ;

}
}
Cdigo 3.28 Instrutor.java

nome=deigo
idade=22
altura=1.85
Cdigo 3.28 config.properties

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean

class="org.springframework.beans.factory.config.PropertyPlaceholder
Configurer">
<property name="location">

<value>classpath:com/targettrust/spring/propertyplaceholderconfigur
er/config.properties</value>
</property>
<property name="properties">
<value>time=Grmio</value>
</property>
</bean>

<bean
id="i"
Spring Framework Framework para desenvolvimento de aplicaes java

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

class="com.targettrust.spring.propertyplaceholderconfigurer.Instrut
or"
>
<property name="nome" value="${nome}" />
<property name="idade" value="${idade}" />
<property name="time" value="${time}" />
<property name="altura" value="${altura}" />
</bean>

</beans>
Cdigo XML 3.11 Registro do PropertyPlaceHolderConfigurer

package com.targettrust.spring.propertyplaceholderconfigurer;

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

public class Teste {

public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(

"/com/targettrust/spring/propertyplaceholderconfigurer/Spring-
beans.xml");

Instrutor i = (Instrutor)ac.getBean("i");
System.out.println("Instrutor: " + i);
}
}
Cdigo 3.29 Teste.java

Na definio do bean PropertyPlaceHolderConfigigurer alm de um conjunto
de arquivos properties possvel passar um objeto Property para ser definido no
prprio Spring em linha, como foi feito no exemplo, assim podemos mesclar
informaes vindas do file system com as informaes definidas nos prprios
metadados do spring.
Existe outro PropertyPlaceHolderConfigurer que o PropertyOverride
Configurer, esse por sua vez ir saber escrever as informaes dos beans, mas o
arquivo de properties deve ter o seguinte formato:


nomeBean.propriedade=valor
outronomeBean.outrapropriedade=outrovalor
maisumnomeBean.maisumapropriedade=maisumvalor
Cdigo 3.29 config.properties para PropertyOverrideConfigurer
Spring Framework Framework para desenvolvimento de aplicaes java

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

Recurso do Spring Framework para podermos carregar mltiplos arquivos de
configuraes de uma s vez. normal termos uma aplicao dividida em camadas
como persistncia, negcio, utilitrios, telas, testes, etc. Neste cenrio dividimos as
configuraes do Spring em diversos arquivos de configuraes, possvel
gerenciar uma bean factory do Spring e parametrizar os arquvios de configurao
que ela ir carregar.
Esse recurso deve ser utilizado somente quando necessrio, pois pode acabar
provendo acoplamento e perda de performance. Evite utiliz-lo em pequenas
aplicaes. O cenrio ideal de utilizao um aplicao JEE com mltiplas camadas
(layers) onde cada camada uma bean factory distinta, nesse caso o
SingletonBeanFactoryLocator pode ser utilizado para criar uma bean factory
hierrquica com suas diversas bean factories. Os Criadores do Spring Framework
recomendam que esse recurso seja utilizado com cautela.
Para utilizar tal recurso necessrio ter um XML na raiz de seu classptah com o
seguinte nome: beanRefFactory.xml, e nesse arquivo vai estar linkado as diversas
beans factories com seus diversos XMLs. Veja o exemplo a baixo.

package com.targettrust.spring.singletonbeanfactorylocator;

public class ObjetoA {}
Cdigo 3.29 ObjetoA.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="A1"
class="com.targettrust.spring.singletonbeanfactorylocator.ObjetoA"

/>
</beans>
Cdigo XML 3.12 Spring-beans-A.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-37
default-lazy-init="true"
>
<bean
id="A2"
class="com.targettrust.spring.singletonbeanfactorylocator.ObjetoA"

/>
</beans>
Cdigo XML 3.13 Spring-beans-B.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="A3"
class="com.targettrust.spring.singletonbeanfactorylocator.ObjetoA"

/>

</beans>
Cdigo XML 3.13 Spring-beans-C.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="A4"
class="com.targettrust.spring.singletonbeanfactorylocator.ObjetoA"

/>
</beans>
Cdigo XML 3.14 Spring-beans-D.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="false"
>

<bean
id="beanFactoryBean"

class="org.springframework.context.support.ClassPathXmlApplicationC
ontext"
>
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-38
<constructor-arg>
<list>

<value>com/targettrust/spring/singletonbeanfactorylocator/Spring-
beans-A.xml</value>

<value>com/targettrust/spring/singletonbeanfactorylocator/Spring-
beans-B.xml</value>

<value>com/targettrust/spring/singletonbeanfactorylocator/Spring-
beans-C.xml</value>
</list>
</constructor-arg>
</bean>

<bean
id="beanFactoryBean2"

class="org.springframework.context.support.ClassPathXmlApplicationC
ontext"
>
<constructor-arg>
<list>

<value>com/targettrust/spring/singletonbeanfactorylocator/Spring-
beans-D.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
Cdigo XML 3.15 beanRefFactory.xml.xml

package com.targettrust.spring.singletonbeanfactorylocator;

import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import
org.springframework.beans.factory.access.SingletonBeanFactoryLocator;

public class Teste {

public static void main(String[] args) {
BeanFactoryLocator bfl =
SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference bf =
bfl.useBeanFactory("beanFactoryBean");

ObjetoA a1 = (ObjetoA)bf.getFactory().getBean("A1");
ObjetoA a2 = (ObjetoA)bf.getFactory().getBean("A2");
ObjetoA a3 = (ObjetoA)bf.getFactory().getBean("A3");

bf = bfl.useBeanFactory("beanFactoryBean2");
ObjetoA a4 = (ObjetoA)bf.getFactory().getBean("A4");

System.out.println("ObjetoA a1: " + a1);
System.out.println("ObjetoA a2: " + a2);
System.out.println("ObjetoA a3: " + a3);
System.out.println("ObjetoA a4: " + a4);

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-39
}
}
Cdigo 3.30 Teste.java

Nesse exemplo existem duas bean factories: beanFactoryBean e
beanFactoryBean2 que so definidas no arquivo BeanRefFactory.xml. A primeira
bean factory tem trs XMLs de configuraes e a segunda tem 1 XML de
configurao.
Na classe de testes instanciado um BeanFactoryLocator que um singleton
e est sob o pattern de ServiceLocator. utilizado o mtodo useBeanFactory para
obtermos um objeto BeanFactoryReference que atravs do mtodo getFactory ir
retornar a bean factory real. Quando necessrio acessar o bean A4 que est em
outra Bean Factory necessrio trocar de bean factory para isso usamos o mtodo
useBeanFactory novamente. Se for necessrio trabalhar com Application context
devemos utilizar outro Locator que o SingletonBeanFactoryLocator.
Spring Framework Framework para desenvolvimento de aplicaes java

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

O Spring framework tem suporte a internacionalizao que a funcionalidade
de prover suporte a aplicaes multi-idiomas. O objeto ApplicationContext
implementa a interfcace MessageSource atravs do qual prove mensagens ou
suporte i18n. Quando um ApplicationContext levantada automaticamente ela
procura por uma fonte de mensagens (MessageSource) definida em seu contexto, o
bean que representa essa fonte de mensagem deve ter o nome messageSource, se
nenhum objeto messageSource for localizado o Spring ir usar um MessageSource
default: StaticMessageSource vazio somente para garantir o funcionamento de
outros componentes.
Atualmente o Spring prove duas implementaes de messageSource, so elas:
StaticMessageSource: utilizada programaticamente para adicionar
mensagens de forma dinmica sua aplicao.
ResourceBundleMessageSource: Mais interessante pois possui suporte a
parte de TextFormat e carrega arquivos atravs dos nomes base.
Para facilitar o acesso a mensagens podemos utilizar a interface
MessageSourceAware que o Spring ir utilizar para injetar o messageSource corrente
em seu bean.
Quando utilizamos esses recursos, devemos ter mltiplos arquivos de idiomas,
por exemplo, ns informaramos o arquivo base como: mensagens no contexto do
Spring, supondo que estamos com o Locale setado para pt_BR deve existir no file
system um arquivo com o nome: mensagems_pt_BR.properties. Veja como usar esses
recursos na prtica conforme mostra o exemplo a seguir:
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.i18n;

import java.util.Locale;

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;

public class Pessoa implements MessageSourceAware{

private String nome;
private int idade;
private MessageSource ms;

public Pessoa() {}

public Pessoa(String nome, int idade) {
super();
this.nome = nome;
this.idade = idade;
}

@Override
public void setMessageSource(MessageSource messageSource) {
ms = messageSource;
}

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

public int getIdade() {
return idade;
}
public void setIdade(int idade) {
if( idade<=0 || idade >= 120 )
throw new
IllegalArgumentException(ms.getMessage("idade.invalida",new
Object[]{idade},Locale.getDefault()));
this.idade = idade;
}

@Override
public String toString() {
return "nome: " + nome + " idade: " + idade;
}
}
Cdigo 3.31 Pessoa.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

idade.invalida=The Age: {0} is not allowed becouse is too older or is
less them 1!
Cdigo 3.32 mensagems_en.properties

idade.invalida=A idade: {0} no aceitvel por que muito velha ou
menor do que 1
Cdigo 3.33 mensagems_pt_BR.properties

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean id="messageSource"

class="org.springframework.context.support.ResourceBundleMessageSou
rce">
<property name="basenames">
<list>
<value>mensagems</value>
</list>
</property>
</bean>

<bean
id="pessoa"
class="com.targettrust.spring.i18n.Pessoa"
/>

</beans>
Cdigo XML 3.16 Spring-beans.xml

package com.targettrust.spring.i18n;

import java.util.Locale;

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

public class Teste {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/i18n/Spring-
beans.xml");

Locale.setDefault(Locale.ENGLISH);
setIdade(ac);

Locale.setDefault(new Locale("pt","BR"));
setIdade(ac);

Spring Framework Framework para desenvolvimento de aplicaes java

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

private static void setIdade(ApplicationContext ac){
Pessoa p = (Pessoa)ac.getBean("pessoa");
p.setNome("Crom");

try{
p.setIdade(200);
}catch(RuntimeException re){
re.printStackTrace();
}
}

}
Cdigo 3.34 Teste.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

1) Crie um objeto pessoa com nome, idade e telefone.
2) Crie um validador para pessoa.
3) Invoque o validador de pessoa em um BeanPostProcessor
4)Externalize as mensagens de erro em um arquivo property e mostre mensagens
i18n caso a idade da pessoa esteja invlida.
5) Crie um property editor que seja possvel passar o nome, idade e telefone da
pessoa apenas na propriedade nome e o property editor espalhar as informaes
em suas propriedades corretas.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 3-45
Espao para anotaes


Spring Framework Framework para Desenvolvimento de Aplicaes Java

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


P
P
e
e
r
r
s
s
i
i
s
s
t
t

n
n
c
c
i
i
a
a

Spring Framework Framework para desenvolvimento de aplicaes java

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

Conhecer a hierarquia de exceptions de banco do Spring;
Saber criar DataSource;
Conhecer os principais recursos do JDBCTemplate;
Saber utilizar o SessionFactoryBean;
Conhecer os principais recursos do HibernateTemplate;
Saber como utilizar transaes declarativas.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-3
Hierarquia de Exceptions

O Spring framework prov uma camada de acesso a dados chamada DAO support
que prove diversas facilidades para trabalhar com JDBC, Hibernate, JDO, JPA. Esse recurso
permite trocar a tecnologia de persistncia com mais facilidade e menos esforo, sem a
necessidade de se preocupar com as execptions que variam de tecnologia para tecnologia.
O Spring tem sua prpria rvore de exceptions traduzindo as exceptions de tecnologias
especficas como SQLException para sua prpria rvore de exceptions, onde sua exception
raiz a DataAccessException. Esses exceptions empacotam a exception raiz, assim voc
no perde nenhuma mensagem original.
O Spring pode encapsular uma exception do Hibernate, por exemplo, em uma outra
exception de sua rvore, isso igual para as exceptions do JDO e da JPA tambm. Este
mecanismo do Spring lhe evita a irritao de ter que tratar exceptions que voc no pode
se recuperar.
Confira a rvore de exceptions do Spring na figura abaixo:

Cdigo 4.1 Hierarquia de Exceptions do Spring

Classes abstratas do modelo de abstrao DAO do Spring: Para prover um modelo
de trabalho mais fcil com todas essas tecnologias de acesso a dados (JDO, JDBC,
Hibernate, JPA) o Spring prove uma srie de classes DAOs abstratas que voc pode
estender. Dentre essas classes temos:
Spring Framework Framework para desenvolvimento de aplicaes java

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

JdbcDaoSupport: Super classe para accesso via JDBC, necessita um DataSource,
prove um instncia de JDBCTemplate.
HibernateDaoSupport: Super classe de acesso via Hibernate, necessita uma
SessionFactory, prove uma instncia de HibernateTemplate.
JdoDaoSupport: Super classe de accesso via JDO, necessita uma
PersistenceManagerFactory, prove uma instncia de JdoTemplate.
JpaDaoSupport: Super classe de accesso via JDO, necessita uma
EntityManagerFactory, prove uma instncia de JpaTemplate.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-5
Acesso a dados usando JDBC

O Spring framework se encarrega de executar as tarefas de baixo nvel da API de
JDBC. O Spring realiza as seguintes operaes:
Define os parmetros da conexo
Abre a conexo
Especifica um Statement
Prepara e executa o Statement
Interam os resultados (se existirem)
Faz o trabalho a cada iterao
Processa as exceptions
Gerencia as transaes
Fecha a conexo
Dessa forma o desenvolvedor pode trabalhar com uma camada de mais alto nvel e mais
produtivas. Essa camada est dividida basicamente em quatro pacotes, core, datasource,
object e suppport que provem objetos de acesso a dados e call backs alm de datasources
e facilidades para acessar stored procedures e functions de bancos.

Trabalhando com DataSources
Quando desejamos manipular dados que esto em algum banco de dados
precisamos de uma conexo com o banco, o Spring realiza essa tarefa atravs de um
DataSource. DataSource parte da especificao JDBC e pode ser visto em forma de uma
connection factory. Isso permite o container esconder os problemas de controle
transacionais e pools de conexes da API do desenvolvedor. Dessa forma possvel isolar as
conexes com os bancos dos cdigos dos desenvolvedores.
Spring Framework Framework para desenvolvimento de aplicaes java

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

No Spring possvel configurar sua fonte de dados de forma que seja possvel obter
o DataSource de uma fonte JNDI. Podemos utilizar um DriverManagerDataSource que
uma simples implementao de DataSource que devemos informar o driver a ser utilizado,
conforme exemplo 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:hsql://C:/db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

</beans>
XML 4.1 DriverManagerDataSource

Para criarmos esse objeto necessrio informar o driver, a url de conexo para o
banco, usurio e a senha. Nesse caso est sendo utilizado uma conexo com o banco de
dados HSQLDB. Esse DataSource no disponibiliza pools de conexes, a cada chamada ser
criada uma conexo nova.
Se voc deseja uma soluo de connection pool out-of-the-box, deve considerar a
soluo da apache o Apache DBCP, possvel utilizar esses framework em conjunto com o
Spring.
Dica: O Spring framework faz a traduo de erros de SQL Genricos para Exceptions mais
especficas, se voc desenvolve alguma regra ou processamento em stored procedures ou
functions de bancos e lavanta exceptions personalizadas no banco, podemos traduzir essas
exceptions personalizadas para exceptions do Java.
Para fazer isso necessrio herdar a classe SQLErrorCodeSQLExceptionTranslator e
implementar o mtodo custom translate onde voc ir traduzir as exceptions.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-7
Trabalhando com JDBCTemplate

Agora vamos ver como executar querys apartir de uma DataSource e um
JDBCTemplate. JDBTemplate um template para acesso a dados via JDBC a classe prove
vrias facilidades de acesso e mtodos que j entregam os dados mais lapidados. Veja
como configurar e executar um cdigo ddl, no exemplo 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:file:///C:\\target\\spring\\db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean
id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"
lazy-init="false"
>
<property name="dataSource" ref="dataSource" />
<property name="lazyInit" value="false" />
</bean>

</beans>
XML 4.2 Configurao de injeo do JDBCTemplate e DataSource.

A Classe JdbcTemplate tem uma srie de mtodos utilitrios, dentre eles podemos
destacar:
Execute (String sql): utilizado para executar comandos ddl.
Update (String sql,Object[] args): utilizado para executar inserts e updates esse
mtodo recebe um Object[] por que ele cria um PreparedStatement. Esse mtodo
pode ser utilizado para efetuar operaes de delete tambm.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-8
queryForObject (String sql,Class requiredType): Esse mtodo executa uma query e
retorna um objeto, especificamos o tipo passando o class do tipo.
queryForObject (String sql,RowMapper rowMapper): Essa sobre escrita desse
mtodo possibilita buscar dados na base e converte-los j para objetos.
queryForInt (String sql): Mtodo que j retorna um int primitivo a partir de uma
query SQL, muito til quando temos que buscar apenas um valor no banco em
alguma tabela de configurao.
queryForList (String sql): Mtodo que executa uma query SQL e trs um java.util.List
como resultado da consulta.
A Classe JdbcTemplate possui vrios overrides dos mtodos de acesso a dados para as
mais diversas situaoes como SQL simples, PreparedStatements, RowMapper, SQL Types.
Veja um exemplo completo de acesso a dados com os principais mtodos do
JdbcTemplate no cdigo 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:file:///C:\\target\\spring\\db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

<bean
id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"
lazy-init="false"
>
<property name="dataSource" ref="dataSource" />
<property name="lazyInit" value="false" />
</bean>
</beans>
XML 4.3 Configurao de injeo do JDBCTemplate e DataSource.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-9
package com.targettrust.spring.jdbc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class TesteCriaTabela {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/jdbc/Spring-
beans.xml");

JdbcTemplate jt = (JdbcTemplate)ac.getBean("jdbcTemplate");

try{
jt.execute("create table _teste (nome varchar(50), numerox
integer); ");
}catch(UncategorizedSQLException e){
System.out.println("A Tabela j existe! ");
jt.update("delete from teste ");
}

jt.update("insert into teste (nome) values (?) ", new
Object[]{"p1"});
jt.update("insert into teste (nome) values (?) ", new
Object[]{"p3"});
jt.update("insert into teste (nome) values (?) ", new
Object[]{"p4"});

jt.update("update teste set nome = ? where nome = ?", new
Object[]{"p2","p1"});
jt.update("delete from teste where nome = 'p4' ");

System.out.println(
jt.queryForObject("select nome from teste where nome = 'p3'
", String.class)
);

ObjetoTeste ot = (ObjetoTeste) jt.queryForObject("select nome from
teste where nome = 'p2' ", new RowMapper(){
public
Object mapRow(java.sql.ResultSet rs, int rowNum) throws java.sql.SQLException {

return new ObjetoTeste(rs.getString("nome"));
}

});

System.out.println(jt.queryForList("select * from teste"));

System.out.println(ot);

}
}
Cdigo 4.1 TesteCriaTabela.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

No Exemplo acima foram definidos dois beans no contexto do Spring, o dataSource
e o jdbcTemplate, no programa java de testes foi requisitado ao Spring o bean
jdbcTemplate e a partir dele foi possivel criar tabelas com o mtodo execute, manipular
dados com o mtodo update e acessar dados com os mtodos queryForXXX.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-11
Session Factory Bean

O Spring prove suporte para gerenciar uma SessionFactory do Hibernate. Essa tarefa
pode ser feita atravs do LocalSessionFactoryBean. Esse bean necessita de uma DataSource
e de recursos de mapeamentos podendo ser um hibernate mappings ou configuraes de
mapeamento feitas no prprio Spring que seram repassadas ao Hibernate. muito comum
utilizar esse tipo de recurso em uma aplicao JEE ou desktop.
O Seguinte exemplo mostra como configurar uma SessionFactoryBean de forma
que o Spring gerencia a SessionFactory do Hibernate com o Banco de dados HSQLDB.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:file:///C:\\target\\spring\\db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

<bean
id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
lazy-init="false"
>
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>com/targettrust/spring/hibernate/Pessoa.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.PointbaseDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>

</beans>
XML 4.4 Configurao de injeo do SessionFactoryBean
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.hibernate;

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

public class TesteSessionFactory {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/hibernate/Spring-
beans.xml");

SessionFactory sf = (SessionFactory)ac.getBean("sessionFactory");
System.out.println(sf.openSession());
}
}
Cdigo 4.2 TesteSessionFactory.java

Para podermos utilizar a integrao do Spring com o Hibernate, so necessrios os
seguintes jars no classpath da aplicao:
hibernate3.jar
jta.jar
dom4j-1.6.1.jar
commons-logging.jar
commons-collections.jar
antlr-2.7.6.jar
hsqldb.jar

Nesse exemplo foi necessrio utilizar o hsqldb.jar, pois nesse jar que esto os drivers de
acesso ao banco de dados hsqldb, se voc quiser utilizar outro banco de dados em sua
aplicao, voc dever trocar esse jar pelo jar apropriado para seu banco de dados.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-13
Hibernate Template

Assim como o JdbcTemplate o template de acesso a dados via jdbc do Spring, o
HibernateTemplate o template de acesso a dados via Hibernate do Spring. Antes do
Spring 2, o Spring provia em seu core suporte para Hibernate 2 e Hibernate 3, a partir de
agora e das novas verses, o Spring s prove acesso ao Hibernate 3 em seu core . No
Projeto Spring Modules existe o suporte para Hibernate 2 para as aplicaes mais antigas.
O HibernateTamplate prove uma srie de comodidades para a utilizao da API do
Hibernate, mas sempre que for necessrio voc pode acessar a prpria API do Hibernate
atravs do Spring. Hibernate template vai cuidar para abrir e fechar a SessionFactory do
Hibernate para ns e automaticamente participar das transaes.
importante destacar alguns mtodos importantes do HibernateTemplate como:
find (String hql): Esse mtodo faz uma busca atravs de um HQL e retorna
uma List.
findByCriteria (DetachedCriteria dt): Esse mtodo realiza uma busca no banco
de dados atravs de um objeto DetachedCriteria do Hibernate e retorna uma
List.
Delete (String hql): Mtodo que deleta dados no banco a partir de uma query
hsql.
saveOrUpdate (Object entity): Mtodo que persiste um objeto no banco de
dados. Esse mtodo realizar um insert se a chave primria (id) for null, do
contrrio ele realizar um update.
Get (Object entity,Serializable id): Mtodo que busca um objeto na base a
partir do Class que representa o objeto e o id do objeto.
Voc pode utilizar os call backs disponibilizados pelo Spring se quiser ter acesso
prpria SessionFactory do Hibernate, porm, com as facilidades do Spring de abrir/fechar a
Session Factory, isso pode ser feito no mtodo execute que recebe um HibernateCallBack
que uma interface do Spring.
Veja no exemplo abaixo a utilizao desses mtodos citados acima:
Spring Framework Framework para desenvolvimento de aplicaes java

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

package com.targettrust.spring.hibernate;

public class Pessoa {

private Long id;
private String nome;
private String email;

public Pessoa() {}

public Pessoa(String nome, String email) {
super();
this.nome = nome;
this.email = email;
}

public Pessoa(Long id, String nome, String email) {
super();
this.id = id;
this.nome = nome;
this.email = email;
}

public Long getId() {
return id;
}

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

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

public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}

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

}
Cdigo 4.3 Pessoa.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.targettrust.spring.hibernate.Pessoa" table="pessoa">
<id name="id" column="id" type="java.lang.Long" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="nome" column="nome" type="java.lang.String"/>
<property name="email" column="email" type="java.lang.String"/>
</class>
</hibernate-mapping>
XML 4.5 Pessoa.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:file:///C:\\target\\spring\\db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>

<bean
id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
lazy-init="false"
>
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>

<value>com/targettrust/spring/hibernate/Pessoa.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.PointbaseDialect</prop>
<!--<prop key="hibernate.hbm2ddl.auto">create</prop> --
>
</props>
</property>
</bean>

<bean
id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate"
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-16
lazy-init="false"
>
<property name="sessionFactory" ref="sessionFactory" />
</bean>

</beans>
XML 4.6 Configurao dos beans do Spring.

package com.targettrust.spring.hibernate;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class HibernateTemplateTest {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/hibernate/Spring-
beans.xml");

HibernateTemplate ht =
(HibernateTemplate)ac.getBean("hibernateTemplate");

testeFind(ht);
testeDetachedCriteria(ht);
testeSave(ht);
testeDelete(ht);
testeGet(ht);

}

private static void testeFind(HibernateTemplate ht){
Object result = ht.find(" from " + Pessoa.class.getName());
System.out.println("Pessoas: " + result);
}

private static void testeDetachedCriteria(HibernateTemplate ht){
DetachedCriteria dt = DetachedCriteria.forClass(Pessoa.class);

List dtResult = ht.findByCriteria(dt);
System.out.println(dtResult);
}

private static void testeSave(HibernateTemplate ht){
Pessoa p = new Pessoa();
String nome = "PessoaHora" + System.currentTimeMillis();
p.setNome(nome);
p.setEmail("noreplay@gmail.com");
ht.saveOrUpdate(p);
ht.flush();

System.out.println(ht.find(" from " + p.getClass().getName() + "
where nome = '" + nome + "'"));
}

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-17
private static void testeDelete(HibernateTemplate ht){

Pessoa p = new Pessoa();
p.setNome("Ze Moleza");
p.setEmail("zemoleza@moleza.mesmo.br");

try{
ht.saveOrUpdate(p);
ht.flush();

System.out.println("Pessoa: " + ht.find(" from " +
Pessoa.class.getName() + " where nome = ?","Ze Moleza"));
ht.delete(p);
ht.flush();

System.out.println("Pessoa: " + ht.find(" from " +
Pessoa.class.getName() + " where nome = ?","Ze Moleza"));

}catch(DataAccessException e){
System.out.println(e.getMessage());
}
}

private static void testeGet(HibernateTemplate ht){
System.out.println("Pessoa carregada com get: " +
ht.get(Pessoa.class, 3L));
}

}
Cdigo 4.4 HibernateTemplateTeste.java

Neste exemplo foi configurado um DataSource para o banco de dados hsqldb e
mais dois beans gerenciados pelo Spring a SessionFactoryBean e o HibernateTemplate. A
partir dessas definies foi requisitado um HibernateTemplate ao Spring pela classe de
testes.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-18
Transaes Declarativas
Para ter esse tipo de recurso necessrio ter um servidor de aplicao como, por
exemplo, JBOSS ou ORACLE IAS, mas se estou em uma aplicao java que roda fora de
uma servidor JEE? Estou fadado a trabalhar com o gerenciamento de transaes em baixo
nvel programaticamente? Se voc usa Spring framework a resposta no! O Spring
capaz de fazer isso por ns e ainda mais, com Spring possvel ter transaes declarativas
com aplicaes JDBC.
De forma programtica podemos ter controle transacional atravs do
TransactionTemplate do Spring que pode ser utilizado com o Hibernate.
HibernateTransactionManager o TransactionManager do Spring para hibernate 3, esse
objeto necessita de uma SessionFactory. Com o transactionTemplate podemos executar
um cdigo atravs do mtodo execute que pode receber um
TransactionCallBackWithoutResult para realizarmos alguma operao no banco. Apesar de
o Spring facilitar esse trabalho, ainda assim essa abordagem custosa e pouco produtiva.
A alternativa para esse problema pode ser o suporte de transaes declarativas do
Spring framework. Esse mecanismo substitui as chamadas programticas por interceptor
AOP aliados a proxys para adicionar o controle transacional.
Dessa forma o componente pode se focar nas regras de negcio e o controle
transacional ficar isolado de forma que poderemos trocar essa implementao sem afetar
as regras de negcio da aplicao.
Com o mecanismo de transaes declarativas do Spring possvel utilizar um
contexto de transao gerenciado pelo HibernateTransactionManager com uma nica
SessionFactory em uma ThreadLocal e depois trocar para transaes distribudas com JPA
apenas trocando o manager de transao, sem afetar nada no seu cdigo j escrito.
Antes do Spring 2.0 nos Springs 1.X.X era utilizado o TransactionProxyFactoryBean,
ainda possvel utilizar esse recurso, o Spring prove total compatibilidade com isso.
Existe uma grande vantagem em utilizar o HibernateTransactionManager por que
ele ir expor a transao a nvel de conexo JDBC por DataSource, ou seja, se criarmos um
JdbcTemplate com o mesmo DataSource da SessionFactory do Transactionanager teremos
controle transacional entre Hibernate e JDBC de forma declarativa.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-19
Para criarmos um controle transacional declarativo com Hibernate precisamos:
DataSource
SessionFactoryBean
HibernateTransactionManager
AOP Config
TxAdvice
Primeiro vamos configurar o DataSource para acesso ao banco de dados, nesse
exemplo vamos utilizar o HSQLDB.

<!-- Definio do Dataource para acesso ao banco HSQLDB -->
<bean
id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="false"
>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:///C:\\target\\spring\\db" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
XML 4.7 DataSource

Apartir desse DataSource vamos cirar a SessionFactory do Hibernate.

<!-- Definio da SessionFactory do Hibernate -->
<bean
id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
lazy-init="false"
>
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>com/targettrust/spring/transaction/Produto.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</prop>
</props>
</property></bean>
XML 4.7 SessionFactoryBean
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-20
Agora o Gerente de Transaes, nesse caso ser o HibernateTransactionManager.
Esse objeto depende da SessionFactory criada anteriormente.

<!-- Definio do TransactionManager, nesse caso o escolhido para a tarefa de
gerenciar as
transaes foi o
org.springframework.orm.hibernate3.HibernateTransactionManager que
gerncia transaes entre Hibernate e JDBC pelo DataSource -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
XML 4.7 HibernateTransactionManager

Agora a configurao AOP para indicar como as classes devem ser interceptadas
pela transao declarativa e quando interceptadas que advice elas devem utilizar. Aqui
informamos que queremos interceptar todos os mtodos da classe ProdutoService, no
importando o mtodo e os parmetros passados. Nessa configurao foi informado para
utilizar um Advice.

<!-- Definio da configurao AOP, aqui criado um pointcut que define os
pontos do sistema
que sero interceptados, nesse caso a execuo de quaisquer mtodos
do ProdutoService.
Depois ele vincula essas classes interceptadas com um advice o
txAdvice;
-->
<aop:config>
<aop:pointcut id="produtoServiceMtodos" expression="execution(*
com.targettrust.spring.transaction.ProdutoService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="produtoServiceMetodos"
/>
</aop:config>
XML 4.7 AOP Config

No Advice estamos definindo que mtodos devem ter escopo transacional de fato.
Os mtodos definidos so: findAll que necessitar de uma transao ativa, se essa
transao no estiver ativa ele ir criar uma nova, esse mtodo est marcado como
somente leitura, ou seja, ele s faz consultas na base. O outro mtodo o salvar* , significa
que todos os mtodos que comecem com salvar sero transacionados e tero
comportamento igual ao findAll, porm esses mtodos salvar podem fazer modificaes
na base de dados.

<!-- Definio do Advide AOP que casa o gerente de transaes com os mtodos
Esse beans informa que mtodos e como esses mtodos devem
ser tratados pela transao -->
<tx:advice id="txAdvice" transaction-manager="txManager">
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 4-21
<tx:attributes>
<tx:method name="salvar*" propagation="REQUIRED" /> <tx:method
name="findAll" propagation="REQUIRED" read-only="true"/>
</tx:attributes></tx:advice>
XML 4.7 TxAdvice

Quando o mtodo salvar do ProdutoService for invocado, o Spring ir criar uma
nova transao se no existir nenhuma ativa, poderamos trocar essa forma de isolamento
transacional. Poderamos usar REQUIRED_NEW que fora a criao de uma nova transao
a cada chamada ao mtodo.

O Spring faz o controle de commit e rollback baseado em exceptions, toda
exception unchecked levantada pelo componente transacionado ir demarcar a transao
para rollback, essa uma maneira simples e eficiente de controlar commit/rollback. Se no
fim da execuo de um mtodo transacionado nenhuma exception for levantada o Spring
ira commitar. Caso alguma exception unchecked, leia-se, por exemplo, RuntimeException
for levantada o Spring ir marcar para Rollback a transao e no final sempre executar um
rollback. Podemos informar exceptions uncheckeds para o Spring e essas eceptions que
ns informarmos sero ignoradas pelo mecanismo de demarcao transacional e o Spring
no ir fazer rollback automtico para essas exceptions.
Essa configurao feita no TxAdvice dentro do TxMethod na propriedade no-
rollback-for onde podemos informar as exceptions.
Spring Framework Framework para desenvolvimento de aplicaes java

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

1) Crie um Data Source para o banco de dados HSQLDB.
2) Defina um Bean JDBCTemplate.
3) Utilize o mtodo queryForObject e liste todos os produtos.
4) Faa um DAO que grave produtos utilizando transaes declarativas e caso o produto a
ser gravado tenha valor <= 0 levante uma exception para invalidar a operao, aps salve-
o.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Espao para anotaes
Spring Framework Framework para Desenvolvimento de Aplicaes Java

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


F
F
a
a
c
c
i
i
l
l
i
i
t
t
a
a
d
d
o
o
r
r
e
e
s
s

Spring Framework Framework para desenvolvimento de aplicaes java

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

Objetivos

Saber configurar e enviar e-mails;
Saber agendar tarefas com JDK Task;
Saber interceptar mtodos com o AOP;
Saber montar um context de test com Junit;
Saber expor um servio via RMI.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-3
Envio de E-mails

O Spring framework prove facilidades para envio de e-mails. Para utilizar os
recursos de envio de e-mail do Spring devemos ter duas bibliotecas adicionais em
nosso classpath, essas bibliotecas so:
Java Mail (mail.jar)
JAF (activation.jar)
Java Mail a implementao padro da SUN para envio de emails e JAF um
framework do Java para trabalhar com imagem JPEG. Se voc baixou a distribuio
completa do Spring na pasta lib voc encontrar essas bibliotecas.
A interface central para o envio de e-mails no Spring a interface MailSender,
na classe SimpleMailMessage temos um objeto simples com getters e setters para
servir de formulrio de mensagens.
O Spring prove uma hierarquia de exceptions para e-mail, facilitando e
padronizando o controle de erros sobre o envio de e-mail, as exceptions
pertencentes a esse mecanismo so:
MailException: Exception base que todas as exceptions de envio de e-mails
estendem.
MailAuthenticationException: Exception que levantada se ocorer algum
erro ao fazer a autenticao no servidor.
MailParseException: Exception que levantada se ocorrer algum erro ao
fazer parte de alguma propriedade da mensagen.
MailPreparationException: Exception que levantada se ocorrer algum
erro e no for possvel preparar a mensagem de e-mail, essa exception
levantada normalmente se voc est utilizando velocity e no conseguiu
iniciar a engine do velocity ou algo do gnero.
MailSendException: Exception que levantada se ocorrer algum erro no
momento de enviar o e-mail.
A interface JavaMailSender adiciona funcionalidades especializadas ao envio de
e-mails como por exemplo suporte a MINE para o MailSender. JavaMailSender
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-4
tambm prove um suporte em forma de call back para a preparao de MINE
chamada MineMessagePreparator.
Agora vamos ver um exemplo prtico de como enviar e-mails com Spring.
Primeiro vamos configurar um MailSender, nesse caso ser o JavaMailSender, ao
definir esse bean precisamos setar as propriedades: host, password, username, onde
host o servidor de e-mail e username e password so usurio e senha.
<bean
id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl"
>
<property name="host" value="host.url.com.br" />
<property name="password" value="senha" />
<property name="username" value="username@host.com.br" />
</bean>
XML 5.1 Definio do bean JavaMailSender

Agora vamos definir o template de mensagens de email padro, aqui nesse
bean que o SimpleMailMessage definimos para onde vai os e-mails atravs da
propriedade from e definimos o titulo do e-mail na propriedade subject.

<bean
id="templateMessage"
class="org.springframework.mail.SimpleMailMessage"
>
<property name="from" value= "user@host.com.br" />
<property name="subject" value="Teste e-mails com Spring" />
</bean>
XML 5.2 Definio do bean templateMessage
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-5
Nesse bean definimos uma mensagem de e-mail especifica, nesse caso um e-
mail apenas de testes, esse bem construdo a partir de um template que um
outro SimpleMailMessage isso feito via injeo de construtor, nesse bean
configuramos para onde vai o e-mail e configuramos tambm o texto de
mensagem, colocar esse tipo de configurao no Spring interessante pois fica fcil
de manter e podemos reaproveitar para vrios trechos do sistema que necessite
enviar esse e-mail.

<bean
id="simpleMailMessage"
class="org.springframework.mail.SimpleMailMessage"
>
<constructor-arg index="0" ref="templateMessage" />
<property name="to" value="dmetallica@gmail.com" />
<property name="text" value=" 123 Testando... " />
</bean>
XML 5.3 Definio do bean simpleMailMessage

Agora vem o programa Java, que faz o envio do e-mail de fato. requisitado
no contexto do Spring um SimpleMailMessage que a mensagem e um MailSender
para o envio.

package com.targettrust.spring.email;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class TesteEnviaEmail {
public static void main(String[] args) {

ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/email/Spring-
beans.xml");

SimpleMailMessage msg =
(SimpleMailMessage)ac.getBean("simpleMailMessage");
MailSender ms = (MailSender)ac.getBean("mailSender");

try{
ms.send(msg);
}
catch(MailException ex) {
ex.printStackTrace();
}

}
}
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-6
Cdigo 5.1 TesteEnviaEmail.java

Uma outra alternativa seria o uso de MimeMessagePreparator. Que uma
interface de call cack utilizada para facilitar o envio de mensagem MIME. Veja como
poderamos usar no cdigo abaixo:
package com.targettrust.spring.email;

import javax.mail.Message;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class TesteMimeMessagePreparetor {
public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext(
"/com/targettrust/spring/email/Spring-beans.xml");

JavaMailSender ms = (JavaMailSender)ac.getBean("mailSender");

MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
mimeMessage.setRecipient(Message.RecipientType.TO,new
InternetAddress("to@server.com"));
mimeMessage.setFrom(new InternetAddress("from@server.com.br"));
mimeMessage.setText("Esse um email de teste!");
}
};
try {
ms.send(preparator);
}
catch (MailException e) {
System.out.println(e.getMessage());
}
}
}
Cdigo 5.2 TesteMimeMessagePreparator.java

Outra soluo interessante seria o uso da MimeMessageHelper que abstrai e
facilita a criao de mensagens. Veja no cdigo abaixo:
package com.targettrust.spring.email;

import javax.mail.internet.MimeMessage;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-7
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class TesteMimeMessageHelper {
public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext(

"/com/targettrust/spring/email/Spring-beans.xml");

JavaMailSender ms = (JavaMailSender)ac.getBean("mailSender");

try{
MimeMessage message = ms.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom("form@server.com.br");
helper.setTo("dest@server.com");
helper.setText("Email MimeMessageHelper");
ms.send(message);
}catch(Exception e){
e.printStackTrace();
}
}
}
Cdigo 5.3 TesteMimeMessageHelper.java

Para enviarmos anexos com o MimeMessageHelper bem simples, basta que
quando criarmos o objeto MimeMessageHelper passemos a MimeMessage e true
para indicar que o e-mail multipart. Depois s adicionar os arquivos atravs do
mtodo addAttachment.

package com.targettrust.spring.email;

import java.io.File;

import javax.mail.internet.MimeMessage;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class TesteMimeMessageHelperAtt {
public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext(

"/com/targettrust/spring/email/Spring-beans.xml");

JavaMailSender ms = (JavaMailSender)ac.getBean("mailSender");


try{
MimeMessage message = ms.createMimeMessage();
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-8
MimeMessageHelper helper = new
MimeMessageHelper(message,true);
helper.setFrom("from@server.com.br");
helper.setTo("to@server.com");
helper.setText("Email MimeMessageHelper");

FileSystemResource file = new FileSystemResource(new
File(".").getCanonicalPath() + "/build.xml");
helper.addAttachment("build.xml", file);

ms.send(message);
}catch(Exception e){
e.printStackTrace();
}
}
}
Cdigo 5.4 TesteMimeMessageHelper.java com envio de anexos.

Poderamos ainda mostrar mandar um e-mail em formato html, isso nos
possibilitaria um leque muito maior de possibilidades em termos de recursos
visuais. Nesse caso poderamos anexar uma imagem e mostrar ela no corpo do e-
mail ao invs de estar anexada a mensagem. Para isso devemos utilizar o mtodo
addInLine e relacionar o id do in line com o id cid html. Veja no exemplo abaixo:

package com.targettrust.spring.email;

import java.io.File;

import javax.mail.internet.MimeMessage;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class TesteMimeMessageHelperAttImg {
public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext(

"/com/targettrust/spring/email/Spring-beans.xml");

JavaMailSender ms = (JavaMailSender)ac.getBean("mailSender");


try{
MimeMessage message = ms.createMimeMessage();
MimeMessageHelper helper = new
MimeMessageHelper(message,true);
helper.setFrom("form@server.com.br");
helper.setTo("dest@server.com");
helper.setText("<html><body><img
src='cid:img1'><br>Email MimeMessageHelper com suporte a imagems em
linha!</body></html>",true);
Spring Framework Framework para desenvolvimento de aplicaes java

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

FileSystemResource file = new FileSystemResource(new
File(".").getCanonicalPath() + "/imagem.jpg");
helper.addInline("img1", file);

ms.send(message);
}catch(Exception e){
e.printStackTrace();
}
}
}
Cdigo 5.5 TesteMimeMessageHelper.java com envio de anexos em linha html.

Importante: Para que a adio de recursos em linha funcione, voc deve adicionar
primeiro o text e depois o recurso respeitando o cid. Se no, pode ser que no
funcione corretamente.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-10
Agendamento de tarefas com JDK Task

O Spring framework prov facilidades para agendamento de tarefas
utilizando JDK Task ou se voc tiver necessidades mais profundas, como manter o
agendamento mesmo que a maquina se desligue e outros recursos mais avanados
voc deve utilizar o suporte do Spring ao Quartz. Nesse tpico vamos ver o
mecanismo de agendamento de tarefas com JDK Task, que pode ser utilizado em
regras de negcio ou algum requisito sistmico como, por exemplo, envio de e-
mails ou checagem de arquivos. Agora voc ver duas maneiras de trabalhar com
Jdk Task.
A primeira envolve menos configurao XML, mas gera um acoplamento
maior com o Spring. A segunda no gera acoplamento com o Spring, porm tem
mais configurao XML.
Vamos comear com o exemplo da forma que envolve menos configurao
XML. Imagine que precisamos saber a hora a todo segundo na sada padro, para
isso criamos um service. Esse Service deve implementar a interface TimerTask e
sobrescrever o mtodo run.

package com.targettrust.spring.jdktask;

import java.util.Date;
import java.util.TimerTask;

public class HoraCertaService extends TimerTask{

@Override
@SuppressWarnings("deprecation")
public void run() {
System.out.println(new Date().getHours() + ":" +
new Date().getMinutes() + ":" +
new Date().getSeconds()
);
}
}
Cdigo 5.6 HoraCertaService.java

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-11
Agora precisamos de um ScheduledTimerTask para o agendamento da tarefa
e configuraes como, atraso inicial e intervalo de tempo que a tarefa deve rodar
novamente.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>

<bean
id="horaCertaService"
class="com.targettrust.spring.jdktask.HoraCertaService"
/>

<bean
id="scheduledTask"

class="org.springframework.scheduling.timer.ScheduledTimerTask"
lazy-init="false"
>
<!-- Espera 0 ms antes de iniciar -->
<property name="delay" value="0" />
<!-- roda de 1 em 1 segundo -->
<property name="period" value="1000" />
<!-- Ira executar a TimerTask horaCertaService -->
<property name="timerTask" ref="horaCertaService" />
</bean>
</beans>
XML 5.4 ScheduledTimerTask bean

Voc pode ver que atravs da propriedade timerTask ligamos o nosso service
de HoraCerta com esse agendamento de tarefa.
Agora s falta injetarmos essa configurao em uma factory de
agendamento de tempo.

<bean
id="timerFactory"
class="org.springframework.scheduling.timer.TimerFactoryBean"
>
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>
XML 5.5 TimerFactoryBean bean

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-12
Agora o XML completo do Spring ficar assim:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>

<bean
id="horaCertaService"
class="com.targettrust.spring.jdktask.HoraCertaService"
/>

<bean
id="scheduledTask"

class="org.springframework.scheduling.timer.ScheduledTimerTask"
lazy-init="false"
>
<!-- Espera 0 ms antes de iniciar -->
<property name="delay" value="0" />
<!-- roda de 1 em 1 segundo -->
<property name="period" value="1000" />
<!-- Ira executar a TimerTask horaCertaService -->
<property name="timerTask" ref="horaCertaService" />
</bean>

<bean
id="timerFactory"
class="org.springframework.scheduling.timer.TimerFactoryBean"
>
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>

</beans>
XML 5.6 Spring-beans.xml

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-13
Para testar basta rodar a classe de testes a baixo:

package com.targettrust.spring.jdktask;

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

public class TestJdkTask {

public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/jdktask/Spring-
beans.xml");
System.out.println(ac);
}
}
Cdigo 5.7 TestJdkTask.java

Porm essa abordagem gera acoplamento da nossa regra de negcios
(HoraCertaService) com os recursos de agendamento de tarefas(TimerTask). Agora
veremos uma abordagem que acaba com esse acoplamento, utilizando o
MethodInvokingTimerTaskFactory Bean.
Primeiro vamos refazer o HoraCertaService retirando o acoplamento com o Spring,
o cdigo fica assim:

package com.targettrust.spring.jdktask;

import java.util.Date;

public class HoraCertaServiceNaoAcoplada {

@SuppressWarnings("deprecation")
public void showTime() {
System.out.println(new Date().getHours() + ":" +
new Date().getMinutes() + ":" +
new Date().getSeconds()
);
}
}
Cdigo 5.8 HoraCertaServiceNaoAcoplada.java

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-14
Perceba que o nome da classe foi alterado para enfatizar que esse um
outro artefato e seu cdigo foi modificado de fato. Agora veja como ficam as
injees do Spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>

<bean
id="horaCertaServiceNaoAcoplada"

class="com.targettrust.spring.jdktask.HoraCertaServiceNaoAcoplada"
/>

<bean
id="scheduledTask"

class="org.springframework.scheduling.timer.ScheduledTimerTask"
lazy-init="false"
>
<!-- Espera 0 ms antes de iniciar -->
<property name="delay" value="0" />
<!-- roda de 1 em 1 segundo -->
<property name="period" value="1000" />
<!-- Ir executar a TimerTask horaCertaService -->
<property name="timerTask" ref="executor" />
</bean>

<bean
id="executor"

class="org.springframework.scheduling.timer.MethodInvokingTimerTask
FactoryBean"
>
<property name="targetObject" ref="horaCertaServiceNaoAcoplada" />
<property name="targetMethod" value="showTime" />
</bean>

<bean
id="timerFactory"
class="org.springframework.scheduling.timer.TimerFactoryBean"
>
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>

</beans>
XML 5.7 Spring-beans-2.xml

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-15
O Que foi feito? Foi definido um bean chamado executor e esse bean um
MethodInvokingTimerTaskFactoryBean, onde a propriedade targetObject define
qual objeto ser invocado e a propriedade targetMethod define qual mtodo ser
chamado.
Depois esse bean associado ao scheduledTask pela propriedade
timerTask=executor.

Agora o teste. Basta rodar a classe Java abaixo:

package com.targettrust.spring.jdktask;

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

public class TestJdkTaskNaoAcoplado {
public static void main(String[] args) {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/jdktask/Spring-
beans-2.xml");
System.out.println(ac);
}
}
Cdigo 5.9 TestJdkTaskNaoAcoplado.java
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-16
@Aspect Support

O Spring tem suporte a recursos AOP, no Spring 2.0 os recurso de aspectos
so feitos utilizando AspectJ, isso significa que os comandos/syntax AspectJ
funciona nas definies de pointcuts. O Mecanismo de AOP do Spring bastante
rico, por que usa AspectJ e por que prove mais facilidades para o uso de aspectos.
Se quisermos utilizar AspectJ teramos que criar artefatos .aj, com os recurso
do Spring, basta criarmos uma classe Java normal, que ser a classe que executar
aes com os objetos interceptados e utilizarmos o conjunto de annotations do
Spring.
Agora vamos definir alguns conceitos centrais de AOP, esses termos no so
termos especficos do Spring, como a tecnologia AOP no to intuitiva valido
formalizar algumas coisas.
Aspect: Paradigma de programao que permite separar e organizar o
cdigo conforme a importncia. Um aspecto pode modificar o
comportamento de um objeto pela adio de comportamento (Advice) sobre
um ponto de execuo (Join Point).
Join Point: Representa um mtodo em execuo, as informaes de um Join
Point so acessveis no corpo de um Advice.
Advice: Ato de pegar um Aspect em um Join Point. uma forma de adicionar
comportamento. Existem trs tipos de Advices:
Before: Ser executado antes da execuo do mtodo.
After: Ser executado depois da execuo do mtodo.
Around: Ter poder de controlar a execuo do mtodo, podendo
proceder a execuo do mtodo ou retornar o qualquer coisa.
Point Cut: Ato de math bater um Aspect com um Join Point, os Advices so
associados com Point Cuts.
Target Object: Objeto Real. Objeto que tem um ou mais advices sobre seus
joins points.
AOP Proxy: Objeto criado pelo framework AOP a fim de executar contratos
de aspectos, como Advices. No Spring os proxys AOP podem ser de dois
tipos: Jdk Dynamic Proxy ou CGLib proxy. Isso transparente para o usurio.
Weaving: a forma de misturar os aspectos com o cdigo target, essa
poltica pode ser feita em tempo de compilao com o AspectJ Compiler ou
em tempo de runtime, o Spring faz weaving em tempo de runtime.

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-17
A Compilao de AOP em Java puramente Java, no necessrio estender a
hierarquia de class loader ou fazer qualquer configurao especial para utilizar
aspectos.
O Spring prove uma soluo eficiente para a maioria dos problemas
corporativos com AOP, se voc necessita de um funcionalidade de math muito
profundo ou interceptar fields a melhor escolha utilizar AspectJ diretamente.
Para utilizarmos os recursos de @AspectJ support do Spring necessrio que os
beans estejam sobre um proxy aop, existe uma forma de fazer isso automtico,
basta colocar <aop:aspectj-autoproxy/> no xml de configurao do Spring. Isso
assume que voc est utilizando o schema xsd correto.
Se voc estiver utilizando o schema antigo em forma de dtd por usar a seguinte
configurao: <beanclass="org.springframework.aop.aspectj.
annotation.AnnotationAwareAspectJAutoProxyCreator" />. A Utilizao de
DTD no Spring 2 no recomendada, use os recursos de xsd ao invs de dtd.
Para que voc utilize esses recursos necessrio ter os seguintes jars no seu
classpath:
aspectjweaver.jar
aspectjrt.jar
Agora vamos a um exemplo completo de uso de @Aspect Support.
Primeiro vamos criar trs Services. Cada um com um propsito distinto, neste
exemplo eles s servem para ilustrar a interceptao de objetos distintos.

Vamos criar uma interface Service, que define o que os Services devem fazer.
Cdigo 5.10 Service.java

Agora as implementaes dos trs services:

package com.targettrust.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ServiceA implements Service{

private static final Log log = LogFactory.getLog(ServiceA.class);
@Override
public void fazAlgo() {
package com.targettrust.spring.aop;

public interface Service {
public void fazAlgo();
}
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-18
log.info("Fiz algo do tipo A");
}
}
Cdigo 5.11 ServiceA.java

package com.targettrust.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ServiceB implements Service{

private static final Log log = LogFactory.getLog(ServiceB.class);

@Override
public void fazAlgo() {
log.info("Fiz algo do tipo B");
}
}
Cdigo 5.12 ServiceB.java

package com.targettrust.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ServiceC implements Service{

private static final Log log = LogFactory.getLog(ServiceC.class);

@Override
public void fazAlgo() {
log.info("Fiz algo do tipo C");
}
}
Cdigo 5.13 ServiceC.java

Agora vamos registrar os beans no Spring, esse registro normal, bean id, classe
e o proxy aop.

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
Spring Framework Framework para desenvolvimento de aplicaes java

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

<aop:aspectj-autoproxy/>

<bean
id="aspecto"
class="com.targettrust.spring.aop.Aspecto"
lazy-init="false"
/>

<bean
id="sa"
class="com.targettrust.spring.aop.ServiceA"
/>

<bean
id="sb"
class="com.targettrust.spring.aop.ServiceB"
/>

<bean
id="sc"
class="com.targettrust.spring.aop.ServiceC"
/>

<bean
id="services"
class="java.util.ArrayList"
>
<constructor-arg index="0">
<list>
<ref bean="sa" />
<ref bean="sb" />
<ref bean="sc" />
</list>
</constructor-arg>
</bean>

</beans>
XML 5.8 Spring-beans.xml

Agora a classe Aspecto. Essa classe possui a annotation @AspectJ e possui
advices de before, after e around.

package com.targettrust.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class Aspecto {

private static final Log log = LogFactory.getLog(Aspecto.class);
Spring Framework Framework para desenvolvimento de aplicaes java

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

@Before("execution(* com.targettrust.spring.aop.Service.*(..))")
public void execucaoDeFazAlgoAntes() {
log.info("To sabendo antes da execuo de Service");
}

@After("execution(* com.targettrust.spring.aop.Service.*(..))")
public void execucaoDeFazAlgoDepois() {
log.info("To sabendo depois da execuo de Serice");
}

@Around("execution(*
com.targettrust.spring.aop.ServiceB.faz*(..)))")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws
Throwable {
Object retVal = pjp.proceed();
log.info("To sabendo around SericeB");
return retVal;
}
}
Cdigo 5.14 Aspecto.java
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-21
Agora vamos classe de testes:

package com.targettrust.spring.aop;

import java.util.List;

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

public class TesteAop {

@SuppressWarnings("unchecked")
public static void main(String[] args) {
ApplicationContext ac = new
ClassPathXmlApplicationContext("/com/targettrust/spring/aop/Spring-
beans.xml");
List<Service> services =
(List<Service>)ac.getBean("services");

for(Service s: services){
s.fazAlgo();
}
}
}
Cdigo 5.15 TesteAop.java

Se rodarmos esses artefatos java, teremos um retorno semelhante ao seguinte:

[INFO 16/09/2007 16:09:00.173 Aspecto.execucaoDeFazAlgoAntes(18) ] To
sabendo antes da execuo de Service
[INFO 16/09/2007 16:09:00.173 ServiceA.fazAlgo(11) ] Fiz algo do tipo A
[INFO 16/09/2007 16:09:00.173 Aspecto.execucaoDeFazAlgoDepois(23) ] To
sabendo depois da execuo de Serice
[INFO 16/09/2007 16:09:00.174 Aspecto.execucaoDeFazAlgoAntes(18) ] To
sabendo antes da execuo de Service
[INFO 16/09/2007 16:09:00.174 ServiceB.fazAlgo(12) ] Fiz algo do tipo B
[INFO 16/09/2007 16:09:00.174 Aspecto.execucaoDeFazAlgoDepois(23) ] To
sabendo depois da execuo de Serice
[INFO 16/09/2007 16:09:00.175 Aspecto.doBasicProfiling(29) ] To sabendo
around SericeB
[INFO 16/09/2007 16:09:00.175 Aspecto.execucaoDeFazAlgoAntes(18) ] To
sabendo antes da execuo de Service
[INFO 16/09/2007 16:09:00.175 ServiceC.fazAlgo(12) ] Fiz algo do tipo C
[INFO 16/09/2007 16:09:00.175 Aspecto.execucaoDeFazAlgoDepois(23) ] To
sabendo depois da execuo de Serice
Cdigo 5.16 Retorno da execuo do TesteAop.java

Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-22
Perceba que primeiro executado um Advice antes de um Service(a, b ou c)
depois executado o prprio service e por ltimo um outro advice de after. Isso
valido para os trs services, mas repare que o service b retorna Sabendo around B
aps o advice after e o retorno da execuo via proceed().
O Spring ainda suporta os seguintes PointCuts:
execution: faz math com uma determinada execuo de mtodo.
within: faz math com mtodos limitados por tipos, exemplo: execuo de
somente tipos DAO within(com.xyz.app.dao..*)
this: limita o math para quando o proxy aop de um determinado tipo, por
exemplo this(com.xyz.app.Serializable) para pegar somente aop proxies que
implementem Serializable
target: limita o math para quando o real target de um determinado tipo,
semelhante ao this s que para o real target.
args: limita o math para quando o join point tem argumentos dos tipos
especificados.
@target: quando o real target tem uma annotation do tipo da especificada
aqui o math feito.
@args: quando o real target tem uma annotation e essa annotation tem os
tipos passados aqui o math feito.
@annotation: quando o mtodo a ser executado tem a annotation
especificada aqui.
@within: quando qualquer tipo de target tem a annotation especificada aqui
o math feito.
O Spring framework tambm tem outros advices disponveis, alm de before,
after e around. So eles:
@AfterReturning: Advice que roda quando o mtodo em execuo faz
math e retorna normalmente.
@AfterThrowing: Advice que roda quando o mtodo em execuo faz
math e retorna uma exception do mesmo tipo da informada.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-23
Testing Support
O Spring framework prove integrao com frameworks de teste unitrio
como por Junit e o TestNG. Dentre os recursos mais importantes podemos destacar
auto-wire automtica para propriedades protected e rollback no final da execuo.
Esse ltimo recurso importantssimo, pois podemos rodar um test e no final ele
sempre dar rollback, assim no iremos sujar a base de dados.
O Spring framerwork permite o uso de frameworks de mock objects como,
por exemplo, o easy mock. Isso muito til, pois dessa forma podemos testar
apenas a camada de services sem persistir na camada DAO, sendo que a camada
DAO pode ser composta de mocks. Assim isolando o teste dos Services e deixando
o teste rpido e funcional.
possvel rodar testes integrados sem a necessidade de se fazer deploy no
servidor de aplicao. Assim podemos testar recursos de SQL, Hibernate e transao
sem o servidor de aplicao, isso d melhor desempenho aos testes.
O mecanismo de test do Spring prove gerenciamento do contexto e cache,
para promover a performance.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-24
AbstractDependencyInjectionSpringContextTests
Essa classe do Spring prove as facilidades de gerenciamento de contexto do
Spring, assim o primeiro mtodo de test a ser executado ser mais lento, porm os
outros vo ser muito mais rpidos pois utilizaram o contexto que j foi iniciado.
Para utilizar esse recurso necessrio implementar o mtodo:
protected String[] getConfigLocations() que deve retornar um array de String
com os arquivos de configuraes do Spring.
O Spring utiliza seus recursos de autoWire by type para dar produtividade
aos testes. Basta declarar um objeto e prover um setter que o Spring ir injetar
automaticamente esse objeto para voc.

package com.targettrust.spring.testing;

import java.util.Date;

public class DataService {
public Date getSysDate(){
return new Date();
}
}
Cdigo 5.17 DataService.java
Spring Framework Framework para desenvolvimento de aplicaes java

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-lazy-init="true"
>
<bean
id="dataService"
class="com.targettrust.spring.testing.DataService"
/>
</beans>
XML 5.9 Spring-beans.xml

package com.targettrust.spring.testing;

import java.util.Date;
import junit.framework.Assert;
import
org.springframework.test.AbstractDependencyInjectionSpringContextTests;

public class TestDataService extends
AbstractDependencyInjectionSpringContextTests {

private DataService dataService;

public void setDataService(DataService dataService) {
this.dataService = dataService;
}

@Override
protected String[] getConfigLocations() {
return new
String[]{"classpath:com/targettrust/spring/testing/Spring-beans.xml"};
}

@SuppressWarnings("deprecation")
public void testDataDoDataService(){
Date d = dataService.getSysDate();
Date l = new Date();

Assert.assertEquals(d.getDay(),l.getDay());
Assert.assertEquals(d.getMonth(),l.getMonth());
Assert.assertEquals(d.getYear(),l.getYear());
}

}
Cdigo 5.18 TesteDataService.java classe de teste de fato.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-26
Podemos utilizar os recursos de injees para testes em propriedades, assim no
necessrio mtodos setters. Para isso precisamos fazer duas operaes.
1 No construtor da classe de testes executar
super.setPopulateProtectedVariables(true).
2 O nome da varivel deve ser o mesmo nome do id do bean no Spring. E deve
ser protected.
Veja o cdigo de exemplo seguinte. Esse cdigo utiliza o mesmo service e o
mesmo arquivo xml do exemplo anterior.

package com.targettrust.spring.testing;

import java.util.Date;
import junit.framework.Assert;
import
org.springframework.test.AbstractDependencyInjectionSpringContextTests;

public class TestDataServiceWithProtected extends
AbstractDependencyInjectionSpringContextTests {

protected DataService dataService;

public TestDataServiceWithProtected() {
super.setPopulateProtectedVariables(true);
}

@Override
protected String[] getConfigLocations() {
return new
String[]{"classpath:com/targettrust/spring/testing/Spring-beans.xml"};
}

@SuppressWarnings("deprecation")
public void testDataDoDataService(){
Date d = dataService.getSysDate();
Date l = new Date();

Assert.assertEquals(d.getDay(),l.getDay());
Assert.assertEquals(d.getMonth(),l.getMonth());
Assert.assertEquals(d.getYear(),l.getYear());
}

}
Cdigo 5.19 TesteDataServiceWithProtected.java classe de teste de fato.
Spring Framework Framework para desenvolvimento de aplicaes java

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

Essa classe possibilita o uso de testes transacionais e em conjunto com
annotations para os testes. As annotations suportadas so:
@DirtiesContext: Annotation que faz o mesmo que o mtodo setDirty isso
far que o contexto seja recarregado nesse mtodo.
@ExpectedException: Annotation que sinaliza que o mtodo deve retornar
um exception especfica, se ele no retornar o teste ir falhar.
@NotTransactionl: Indica que esse mtodo roda fora do contexto de
transaes do Spring.
@Repeat: Essa annotation recebe um nmero, por exemplo, 5. O Spring ir
repetir esse teste cinco vezes.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-28
AbstractTransactionalDataSourceSpringContextTests
Essa classe de testes utilizada para adicionar o suporte a transaes, e no
final do teste ir fazer roll back automaticamente. Se existir a necessidade de
efetuar o commit por causa de seu banco de dados, voc pode executar o mtodo
super.setComplete() no construtor, isso far com que o commit seja executado ao
invs do rollback.
Veja como utilizar esse recurso na prtica com esse teste abaixo:
package com.targettrust.spring.testing;

import org.springframework.jdbc.core.JdbcTemplate;
import
org.springframework.test.AbstractTransactionalDataSourceSpringContextTest
s;

import com.targettrust.spring.transaction.Produto;
import com.targettrust.spring.transaction.ProdutoService;

public class TesteTransactionWithRollBack extends
AbstractTransactionalDataSourceSpringContextTests {

protected ProdutoService produtoService;
protected JdbcTemplate jdbcTemplate;

public TesteTransactionWithRollBack() {
//super.setComplete();
super.setDefaultRollback(true);
super.setPopulateProtectedVariables(true);
}

@Override
protected String[] getConfigLocations() {
return new
String[]{"classpath:/com/targettrust/spring/transaction/Spring-
beans.xml"};
}

public void testSavePessoa() throws Exception{
Produto p = new Produto();
p.setNome("PRODUTO QUE NO DEVE APARECER NO BANCO DE DADOS");
p.setTipo("FANTASMA");
p.setValor(666d);

produtoService.salvar(p);
System.out.println(produtoService.findAll());
}

}
Cdigo 5.20 TesteTransactionalWithRollBack.java classe de teste de fato.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-29
Remoting com RMI

O Spring framework prove recursos de remoting. Imagine que voc tem um
sistema construdo com Spring em sua corporao e um sistema novo necessita
acessar dados do outro sistema, uma soluo expor os servios do Spring j
existentes e assim no ter retrabalho e ter aproveitamento de cdigo, centralizao
das regras de negcio e produtividade. Esses requisitos so possiveis e fceis de se
atingirem com os recursos de remoting do Spring.
O Spring pode expor um servio das mais diversas maneiras como: JMS, JMX,
RMI, Http Invoker, Burlap, Hessian e at mesmo EJB. Nesse captulo vamos estudar a
forma do Spring expor um servio via RMI.
O RMI uma forma de RPC s que para objetos e permite efetuarmos
chamadas remotas em aplicaes desenvolvidas em Java.
A vantagem do RMI que podemos trafegar objetos complexos entre
sistemas, sem termos muita preocupao com o protocolo.Para trafegarmos um
objeto via o remoting RMI do Spring esse objeto deve obrigatoriamente ser
Serializable.
Para fazer a exposio de um servio do Spring via RMI basta utilizarmos o
RmiServiceExporter. Para fazer a exposio obrigatrio o uso de interfaces, deve
existir uma interface publica no servio. Essa interface ser utilizada pelo sistema
que deseja acessar os dados.
O nico ponto ruim que temos que abrir uma porta para tal operao, isso
deve ser feito com cuidado por questes de segurana.
Vamos aplicao prtica. Primeiro vamos definir uma interface de acesso, a
HoraService.

package com.targettrust.spring.remoting;

import java.util.Date;

public interface HoraService {
public Date getDate();
}
Cdigo 5.21 HoraService.java
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-30
Agora vamos fazer uma implementao de servio padro para essa interface.

package com.targettrust.spring.remoting;

import java.util.Calendar;
import java.util.Date;

public class HoraServiceImpl implements HoraService{
public Date getDate() {
return Calendar.getInstance().getTime();
}
}
Cdigo 5.22 HoraServiceImpl.java

Configurao do Spring no servidor aplicao que expe o Servio para outras
aplicaes acessarem.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="horaService"
class="com.targettrust.spring.remoting.HoraServiceImpl"
/>

<bean
class="org.springframework.remoting.rmi.RmiServiceExporter"
>
<property name="serviceName" value="Target-HoraService"/>
<property name="service" ref="horaService"/>
<property name="serviceInterface"
value="com.targettrust.spring.remoting.HoraService"/>
<property name="registryPort" value="1199"/>
</bean>
</beans>
XML 5.10 server-beans.xml
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-31
Nesse arquivo de configurao do Spring, foi registrado o service de hora, o
HoraServiceImpl. E exposto como RMI atravs do RmiServiceExporter esse projeto
tem quatro propriedades que devem ser injetadas, so elas:
serviceName: Nome do Servio que o cliente ir se conectar.
service: Ref para o bean que o servio real.
serviceInterface: Apontamento para a interface do servio.
registryPort: Porta na qual ser disponibilizado o RMI.
Agora vamos ao programa server quer ficar expondo o servio por tempo
indeterminado, para fins didticos foi feito um while(true).

package com.targettrust.spring.remoting;

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

public class ContextServer {

@SuppressWarnings("unused")
public static void main(String[] args) throws Throwable {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/remoting/server-
beans.xml");
while(true){
Thread.sleep(10000L);
}
}
}
Cdigo 5.23 ContextServer.java
Agora vamos a configurao xml do cliente, que poderia ser um programa Java
com RMI normal, nesse exemplo vamos utilizar os prprios recursos do Spring para
isso.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<bean
id="horaService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
>
<property name="serviceUrl" value="rmi://localhost:1199/Target-
HoraService"/>
<property name="serviceInterface"
value="com.targettrust.spring.remoting.HoraService"/>
</bean>
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-32
</beans>
XML 5.11 cliente-beans.xml
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-33
Na configurao do Spring foi definido um bean, o bean horaService que
est vindo de um proxy remoto. Dessa forma podemos trabalhar com o servio
normalmente, at mesmo injet-lo em outros beans colaboradores. Para essas
operaes de suma importncia a interface.
Na definio desse bean passamos dois parmetros so eles:
serviceURL: URL apontando para onde est o servio RMI.
serviceInterface: Apontando para qual interface esse servio est
exposto.
Para finalizar o programa cliente que chama o server e testa o servio
completo de RMI.
Cdigo 5.24 ContextCliente.java
package com.targettrust.spring.remoting;

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

public class ContextCliente {
@SuppressWarnings("unused")
public static void main(String[] args) throws Throwable {
ApplicationContext ac =
new
ClassPathXmlApplicationContext("/com/targettrust/spring/remoting/cliente-
beans.xml");

HoraService hs = (HoraService)ac.getBean("horaService");
System.out.println("Hora vinda do Service: " + hs.getDate());

}
}
Spring Framework Framework para desenvolvimento de aplicaes java

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

1) Crie um Aspecto para logar todas as chamadas aos dados de um sistema.
2) Crie um agendamento com JDK Task que de cinco em cinco segundos manda um
e-mail para uma pessoa informando se ouve alguma mudana no sistema.
3) Crie um servio de calculadora e exporte-o via RMI, faa um programa cliente
com o suporte de Junit do Spring e suas classes de teste.
Spring Framework Framework para desenvolvimento de aplicaes java

Diego Pacheco http://diego-pacheco.blogspot.com 5-35
Espao para anotaes

Você também pode gostar