Spring Framework 20 Diego Pacheco

download Spring Framework 20 Diego Pacheco

of 168

Transcript of Spring Framework 20 Diego Pacheco

Spring Framework (2.0) Framework para Desenvolvimento de Aplicaes em Java

Diego PachecoDez/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

Sumrio1. Introduo .................................................................................................................... 1-1Objetivos ...................................................................................................................................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-1Objetivos ...................................................................................................................................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-1Objetivos ...................................................................................................................................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-17Diego Pacheco http://diego-pacheco.blogspot.com I

Spring Framework Framework para desenvolvimento de aplicaes Java

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

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

II

Spring Framework Framework para desenvolvimento de aplicaes Java

4. Persistncia .................................................................................................................. 4-1Objetivos ...................................................................................................................................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-1Objetivos ...................................................................................................................................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

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

III

Spring Framework Framework para Desenvolvimento de Aplicaes Java

1. Introduo

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

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-2

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-3

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-4

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-5

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-6

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-7

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-8

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-9

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-10

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-11

Spring Framework Framework para desenvolvimento de aplicaes java

DownloadO 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.

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

1-12

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-13

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-14

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

1-15

Spring Framework Framework para desenvolvimento de aplicaes java

Espao para anotaes

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

1-16

Spring Framework Framework para Desenvolvimento de Aplicaes Java

2. Container IoC

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

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

2-2

Spring Framework Framework para desenvolvimento de aplicaes java

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:Diego Pacheco http://diego-pacheco.blogspot.com 2-3

Spring Framework Framework para desenvolvimento de aplicaes java

package com.targettrust.spring.bad; import java.util.List; public class Autor { private String nome; private List 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 getLivros() { return livros; } public void setLivros(List livros) { this.livros = livros; } }

Cdigo 2.1 Autor.java

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

2-4

Spring Framework Framework para desenvolvimento de aplicaes java

package com.targettrust.spring.bad; public class Livro {

private private private private

Autor autor; String titulo; String editora; 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.javaDiego Pacheco http://diego-pacheco.blogspot.com 2-5

Spring Framework Framework para desenvolvimento de aplicaes java

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 livros = new ArrayList(); 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 achados = new ArrayList(); 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

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

2-6

Spring Framework Framework para desenvolvimento de aplicaes java

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 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?

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

2-7

Spring Framework Framework para desenvolvimento de aplicaes java

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 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 getPublicaveis() { return publicaveis; } public void setPublicaveis(List publicaveis) { this.publicaveis = publicaveis; } public Listavel getList() { return list; } public void setList(Listavel list) { this.list = list; } }

Cdigo 2.5 Autor.javaDiego Pacheco http://diego-pacheco.blogspot.com 2-8

Spring Framework Framework para desenvolvimento de aplicaes java

package com.targettrust.spring.bad.ok; public class Livro implements Publicavel{ private private private private Autor autor; String titulo; String editora; 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

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

2-9

Spring Framework Framework para desenvolvimento de aplicaes java

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

Cdigo 2.6 Livro.javapackage com.targettrust.spring.bad.ok; public interface Publicavel { public String getAutor(); public String getNome(); public String getTipo(); }

Cdigo 2.7 Publicavel.javapackage com.targettrust.spring.bad.ok; import java.util.List; public interface Listavel { public List list(String nome); }

Cdigo 2.8 Listavel.java

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

2-10

Spring Framework Framework para desenvolvimento de aplicaes java

package com.targettrust.spring.bad.ok; import java.util.ArrayList; import java.util.List; public class Listar implements Listavel{ public List list(String nome) { Autor a = new Autor("Diego Pacheco"); List publicaveis = new ArrayList(); 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 achados = new ArrayList(); for(Publicavel p: publicaveis){ if (p.getAutor().equals(nome)) achados.add(p); } return achados; } }

Cdigo 2.9 Listar.javapackage 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

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

2-11

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

2-12

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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/Springbeans.xml"); Object bean = bf.getBean("autor"); System.out.println("Autor: " + bean); } }

Cdigo 2.11 Obtendo um bean do Spring

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

2-13

Spring Framework Framework para desenvolvimento de aplicaes java

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

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

2-14

Spring Framework Framework para desenvolvimento de aplicaes java

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 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(); 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"));

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

2-15

Spring Framework Framework para desenvolvimento de aplicaes java

ufs.add(new ufs.add(new ufs.add(new ufs.add(new ufs.add(new }

Uf("Rorima","RR")); Uf("So Paulo","SP")); Uf("Santa Catarina","SC")); Uf("Sergipe","SE")); 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 getUfsBrazil(){ return ufs; } public void showInstance(){ System.out.println(super.toString()); } public String toString() { return sigla; } }

Cdigo 2.14 Bean Uf

Cdigo XML 2.2 Spring-beans.xml

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

2-16

Spring Framework Framework para desenvolvimento de aplicaes java

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/Springbeans.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.

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

2-17

Spring Framework Framework para desenvolvimento de aplicaes java

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:

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

Lazy InitializationOutro 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.

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

2-18

Spring Framework Framework para desenvolvimento de aplicaes java

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:

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, 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.

ento sempre que possvel altere essa

Cdigo XML 2.4 Spring-beans.xml um exemplo de default lazy initialization.

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

2-19

Spring Framework Framework para desenvolvimento de aplicaes java

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.

Scoposingleton prototype request *

DescrioUma nica instncia de objeto para todo o contexto do Spring. Mltiplas instncias de um objeto para o container do Spring. 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.

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

2-20

Spring Framework Framework para desenvolvimento de aplicaes java

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.

Cdigo XML 2.5 Spring-beans.xml xml de configurao.

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

2-21

Spring Framework Framework para desenvolvimento de aplicaes java

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/Springbeans.xml"); SimpleBean SimpleBean SimpleBean SimpleBean beanA beanA1 beanB beanB1 = = = = (SimpleBean)bf.getBean("beanA"); (SimpleBean)bf.getBean("beanA"); (SimpleBean)bf.getBean("beanB"); (SimpleBean)bf.getBean("beanB"); : : : : " " " " + + + + beanA); beanA1); beanB); beanB1);

System.out.println("BeanA System.out.println("BeanA1 System.out.println("BeanB System.out.println("BeanB1 } }

Cdigo 2.18 Teste de Scopes.

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

2-22

Spring Framework Framework para desenvolvimento de aplicaes java

Criando seu prprio scopeNo 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.Diego Pacheco http://diego-pacheco.blogspot.com 2-23

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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 tl; public ThreadLocalScope() { tl = new ThreadLocal(); tl.set(new HashMap()); } @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);

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

2-25

Spring Framework Framework para desenvolvimento de aplicaes java

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:

Cdigo XML 2.7 Definio de scope customizado.

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

2-26

Spring Framework Framework para desenvolvimento de aplicaes java

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 private private private String nome; Integer idade; boolean desconto; 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.Diego Pacheco http://diego-pacheco.blogspot.com 2-27

Spring Framework Framework para desenvolvimento de aplicaes java

Cdigo XML 2.8 Configurao de injeo via setterpackage 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/Springbeans.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.

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

2-28

Spring Framework Framework para desenvolvimento de aplicaes java

Injeo via construtorEsta 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:

Cdigo XML 2.9 Configurao de injeo via construtor

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

2-29

Spring Framework Framework para desenvolvimento de aplicaes java

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.

Cdigo XML 2.10 Exemplo de tipo de argumento para construtor.

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

2-30

Spring Framework Framework para desenvolvimento de aplicaes java

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:

Cdigo XML 2.11 Exemplo de tipo de argumento para construtor com index.

Injeo de coleesPor 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: , , e . Considerando o seguinte exemplo: Diego Rod Alef 1 diego 2 Rod

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

2-31

Spring Framework Framework para desenvolvimento de aplicaes java

Ze JoZe MaisEh

estadio.luz=forte estadio.taman.hq.full=grande estadio.fundac.since=10/10/2001 estadio.status.now=ativo

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 import import import java.util.List; java.util.Map; java.util.Properties; java.util.Set;

public class Estadio { private private private private Set pessoas; Map cadeiras; List vededoresPipoca; Properties detalhes;

public Estadio() {} public Set getPessoas() { return pessoas; } public void setPessoas(Set pessoas) { this.pessoas = pessoas; }

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

2-32

Spring Framework Framework para desenvolvimento de aplicaes java

public Map getCadeiras() { return cadeiras; } public void setCadeiras(Map cadeiras) { this.cadeiras = cadeiras; } public List getVededoresPipoca() { return vededoresPipoca; } public void setVededoresPipoca(List 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/Springbeans.xml"); System.out.println(bf.getBean("estadio")); } }

Cdigo 2.26 TestCollections.java Classe de testes.

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

2-33

Spring Framework Framework para desenvolvimento de aplicaes java

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: forte grande 10/10/2001 ativo

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 .

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 ruas; public Cidade() {} public LinkedList getRuas() { return ruas; } public void setRuas(LinkedList ruas) { this.ruas = ruas; } }

Cdigo 2.27 Cidade.java Classe que usa LinkedList.

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

2-34

Spring Framework Framework para desenvolvimento de aplicaes java

java.util.LinkedList true 1 2 3

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.Diego Pacheco http://diego-pacheco.blogspot.com 2-35

Spring Framework Framework para desenvolvimento de aplicaes java

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 cidades; public Estado() {} public String getSigla() { return sigla; } public void setSigla(String sigla) { this.sigla = sigla; }

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

2-36

Spring Framework Framework para desenvolvimento de aplicaes java

public List getCidades() { return cidades; } public void setCidades(List cidades) { this.cidades = cidades; } @Override public String toString() { return sigla + " cidades: " + cidades; } }

Cdigo 2.28 Estado.java Classe que utiliza a colaboradora.

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

2-37

Spring Framework Framework para desenvolvimento de aplicaes java

Porto Alegre Gravata

Cdigo XML 2.15 Injees de colaboradores.

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

2-38

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

2-39

Spring Framework Framework para desenvolvimento de aplicaes java

Instanciando o contexto WebO 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: contextConfigLocation /WEB-INF/Spring-beans.xml org.springframework.web.context.ContextLoaderListener

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:

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

2-40

Spring Framework Framework para desenvolvimento de aplicaes java

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: Spring WEB Exemplo de Spring com WEB-Tier
A Data atual :

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.

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

2-41

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

2-42

Spring Framework Framework para desenvolvimento de aplicaes java

Espao para anotaes

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

2-43

Spring Framework Framework para Desenvolvimento de Aplicaes Java

3. Manipulao de Beans

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

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

3-2

Spring Framework Framework para desenvolvimento de aplicaes java

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. 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:

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

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

3-3

Spring Framework Framework para desenvolvimento de aplicaes java

Init-Metohd e InitializingBeanO 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

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

3-4

Spring Framework Framework para desenvolvimento de aplicaes java

Cdigo XML 3.2 injeo com uso de init-methodpackage 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/Springbeans.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 destroymethod 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

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

3-5

Spring Framework Framework para desenvolvimento de aplicaes java

mtodo destroy(). Esse mtodo ser invocado no momento da destruio do contexto do Spring.

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

3-6

Spring Framework Framework para desenvolvimento de aplicaes java

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 {

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

3-7

Spring Framework Framework para desenvolvimento de aplicaes java

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:

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/Springbeans.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.

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

3-9

Spring Framework Framework para desenvolvimento de aplicaes java

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() {

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

3-10

Spring Framework Framework para desenvolvimento de aplicaes java

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

Cdigo XML 3.4 injeo com uso de validatorpackage 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);

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

3-11

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

3-12

Spring Framework Framework para desenvolvimento de aplicaes java

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 subpropriedades 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 + " ]";

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

3-13

Spring Framework Framework para desenvolvimento de aplicaes java

} }

Cdigo 3.8 Funcionario.javapackage 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

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

3-14

Spring Framework Framework para desenvolvimento de aplicaes java

Cdigo XML 3.5package 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

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

3-15

Spring Framework Framework para desenvolvimento de aplicaes java

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 nome conta.valor

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

filhos[2]

estado[poa]

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

3-16

Spring Framework Framework para desenvolvimento de aplicaes java

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 initbean. 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.

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

3-17

Spring Framework Framework para desenvolvimento de aplicaes java

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.javapackage com.targettrust.spring.beanpostprocessors; public class ObjetoB { }

Cdigo 3.13 ObjetoB.javapackage com.targettrust.spring.beanpostprocessors; public class ObjetoC { }

Cdigo 3.14 ObjetoC.java

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

3-18

Spring Framework Framework para desenvolvimento de aplicaes java

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

Cdigo XML 3.6 Xml de configuraes

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

3-19

Spring Framework Framework para desenvolvimento de aplicaes java

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.

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

3-20

Spring Framework Framework para desenvolvimento de aplicaes java

BeanFactoryPostProcessorsSimilar 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; }