2. Agenda
Introdução;
Container de inversão de controle;
Anotações;
Persistência de dados;
Programação orientada a aspectos;
Spring MVC;
Testes unitários;
Tópicos avançados;
Conclusão.
3. Introdução
O que é Spring ?
◦ Definição oficial: “Plataforma para seu
código Java que provê um suporte
infraestrutural para o desenvolvimento de
aplicações”;
◦ Spring encarrega-se do trabalho de
montar a aplicação para que você possa
preocupar-se em resolver os problemas
de negócio;
◦ Por fim, Spring permite que aplicações
sejam desenvolvida utilizando-se apenas
POJOs.
4. Plataformas alvo
Devido a sua arquitetura baseada em
POJOs, Spring pode ser utilizada para
desenvover aplicações:
◦ JSE:
Pois trata-se de uma plataforma leve e que não
requere um servidor de aplicações;
◦ JEE:
Pois consegue prover serviços importantes
para o desenvolvimento de aplicações
corporativas, tais como: transações,
sergurança e persistência.
5. Spring vs EJB 3 (1/2)
Vantagens do EJB 3:
◦ Plataforma padrão de mercado, definida
pelo JCP (Java Community Process) para
o desenvolvimento de aplicações JEE;
◦ Total integração com os servidores de
aplicação;
◦ Grande produtividade após a introdução
das anotações com especificação JEE
5.0.
6. Spring vs EJB 3 (2/2)
Vantagens do Spring:
◦ Plataforma leve, não necessita de um
servidor de aplicações;
◦ Sistemas podem executar em qualquer
ambiente JSE e JEE;
◦ Apesar de não ser padrão, Spring é um
framework bastante popular;
◦ Sistemas feitos em Spring são fáceis de
testar;
◦ Plataforma desenvolvida de forma a
incentivar o reuso e boas práticas de
projeto de quem a utiliza.
7. Quem usa Spring ?
PETROBRAS;
Bradesco;
Empresas de TI:
◦ Politec - Brasil;
◦ Stefanini - Brasil;
◦ Indra Company – Espanha;
LinkedIn !!!
◦ Detalhes: 2 data centers, ~600 máquinas,
~100 componentes e ~30 milhões de
usuários (fonte: Raible Designs)
8. Inversão de controle (1/3)
Paradigma tradicional:
◦ As dependências entre os objetos são
resolvidas diretamente, ou seja, são
definidas diretamente durante a
implementação.
Dependência lógica «Interface»
AlgoritmoJuro
Associação s
CalculaDivid
a Generalização
Dependência direta
JurosComposto
JurosSimples
s
9. Inversão de controle (2/3)
Inversão de controle ou injeção de
dependências (por Martin Fowler):
◦ As dependências são injetadas
indiretamente através de uma entidade
externa.
Dependência lógica «Interface»
AlgoritmoJuro
Associação s
CalculaDivid
a Generalização
Injeta Dependência 3
2
dependência injetada
JurosComposto
JurosSimples
s
Spring
1 Instancia dependência
10. Inversão de controle (3/3)
Vantagens:
◦ Ausência de código de montagem;
◦ Incentivo à baixo acoplamento e reuso
através de utilização de interfaces e a
criação de componentes;
◦ Com a montagem separada da
implementação fica fácil trocar
componentes e testar diferentes soluções
sem a necessidade de modificar o
restante do sistema.
11. Primeiro exemplo
Vamos implementar um simples
calculador de dívidas utilizando
Spring;
Esta aplicação será composta por 3
classes, 1 interface e 1 arquivo de
configuração.
Arquitetura do exemplo:
CalculaDivid
«Interface»
AlgoritmoJuro
a Associação s
Generalização
JurosComposto
JurosSimples
s
18. Executando o exemplo
1
2
3
1 Montagem da aplicação / Obtenção de um contexto aplicacional Spring
2 Obtenção de um bean definido no contexto aplicational (serviço);
3 Invocação do método de negócios.
Resultado da execução:
****************************
Montande inicial: 1000,00
Taxa de juros: 0,50
Quantidade de meses: 3
Montande final: 3375,00
****************************
19. Conceitos básicos
Beans;
Como criar beans;
Quando criar beans;
Definição de escopo;
Ciclo de vida;
Propriedades;
Templates e especialização;
Utilizando mais de 1 arquivo de
configuração;
Propriedades externas;
Contextos de aplicação.
20. Beans
Bean:
◦ Qualquer objeto definido dentro do
Spring;
Um Bean Spring é um POJO, não
precisa ser um Java Bean;
Único requisito:
◦ As propriedades devem seguir a
convenção get/set;
Definição básica de um bean:
◦ <bean id=“id_bean”
21. Como criar beans (1/12)
Formas de criar um bean:
◦ Construtor;
◦ Método de fábrica (factory method);
◦ Bean de fábrica (factory bean);
Todas as formas de criação permitem
a passagem de parâmetros.
22. Como criar beans (2/12)
Construtor sem argumentos
◦ É invocado o construtor sem argumentos
(caso haja) ou o construtor padrão da
classe.
Arquivo de configuração:
23. Como criar beans (3/12)
Construtor com argumentos:
◦ Classe: 1
2 3
◦ Arquivo de configuração:
1
2
3
24. Como criar beans (4/12)
Construtor com argumentos:
◦ Percebam que na definição dos
parâmetros do construtor não é indicado
um nome, portanto, estes devem ser
informados na mesma ordem que estão
definidos na implementação do método.
25. Como criar beans (5/12)
Método de fábrica:
◦ Utilizado quando existe um método
especializado na criação de um
determinado objeto;
◦ Padrão de projeto Factory Method (GoF).
27. Como criar beans (7/12)
Método de fábrica:
◦ Arquivo de configuração:
◦ Atenção !
Caso existam parâmetros para o método de
fábrica, estes devem ser informados utilizando
o elemento constructor-arg.
28. Como criar beans (8/12)
Bean de fábrica:
◦ Utilizado quando existem objetos
especializados na criação de outros
objetos; Instância do padrão de projeto
AbstractFactory – GoF.
«Interface»
Serviço FábricaAbstrat
a
FábricaConcreta FábricaConcreta FábricaConcreta
1 2 … N
29. Como criar beans (9/12)
Bean de fábrica:
◦ Interface da fábrica:
30. Como criar beans (10/12)
Bean de fábrica:
◦ Implementação da fábrica:
31. Como criar beans (11/12)
Bean de fábrica:
◦ Arquivo de configuração:
1
2
3
1 Instanciação da fábrica;
2 Referência à fábrica criada;
3 Método da fábrica utilizado para instanciar um algorítmo.
32. Como criar beans (12/12)
Bean de fábrica:
◦ Novamente quaisquer parâmetros que
sejam necessários passar na criação de
um objeto utilizando um bean de fábrica
devem ser informados utilizando
constructor-arg.
33. Quando criar beans
A plataforma Spring permite
especificar quando os beans serão
instanciados:
◦ Quando o ApplicationContext for criado
(forma padrão);
◦ Apenas quando o bean for utilizado (lazy-
loading):
Definição para um bean:
<bean id=“id_bean” class=“caminho_classe” lazy-
init=“true” …
Definição global:
<beans default-lazy-init=“true” …
34. Escopo de um bean (1/8)
Para Spring, o escopo é a forma como
as instâncias de um bean são obtidas
e mantidas.
Existem dois possíveis escopos:
◦ Singleton (padrão):
Apenas uma instância do bean é criada e
retornada sempre que solicitada ao
ApplicationContext;
◦ Prototype:
Uma nova instância é criada sempre que um
bean é solicitado ao ApplicationContext.
35. Escopo de um bean (2/8)
Singleton:
◦ Definição (opcional):
<bean id=“…” class=“…” scope=“singleton” …
◦ Exemplo:
Para ilustrar o funcionamento dos escopos
iremos modificar o nosso primeiro exemplo
para exibir uma mensagem no console sempre
que uma instância do bean for criada.
36. Escopo de um bean (3/8)
Exemplo singleton / classe:
37. Escopo de um bean (4/8)
Exemplo singleton:
◦ Arquivo de configuração:
1
1 Definição do escopo. Lembrem-se que no caso do singleton é opcional.
38. Escopo de um bean (5/8)
Exemplo singleton:
◦ Saída:
Foi criada a instância 1
39. Escopo de um bean (6/8)
Prototype:
◦ Definição:
<bean id=“…” class=“…” scope=“prototype” …
◦ Exemplo:
Iremos modificar o exemplo anterior alterando
apenas o valor do escopo para prototype para
então verificar o que é causado em sua
execução.
40. Escopo de um bean (7/8)
Exemplo prototype / arquivo de config:
1
1 Definição do escopo.
Resultado da execução:
Foi criada a instância 1
Foi criada a instância 2
Foi criada a instância 3
…
Foi criada a instância 7
Foi criada a instância 8
Foi criada a instância 9
Foi criada a instância 10
41. Escopo de um bean (8/8)
O tipo do escopo de um bean tem
grandes impactos na utilização de
recursos e na forma como os beans
devem ser implementados;
Beans prototype usam mais memória,
porém cara instância possui um estado
independente (estado prototype);
Beans singleton são compartilhados por
todos os threads da aplicação;
O escopo deve ser escolhido com
atenção.
42. Ciclo de vida (1/6)
É possível acompanhar o processo de
criação e destruição dos beans;
Para isto, Spring provê uma forma de
adicionar código que será executado
após a criação e/ou antes da
destruição de um bean;
Esta configuração pode ser feita para
um bean individual ou de forma
global.
43. Ciclo de vida (2/6)
Interceptando a criação de um bean;
Atributo init-method (local):
◦ <bean id=“…” class=“…” init-
method=“init” …
Atributo default-init-method (global):
◦ <beans default-init-method=“init” …
Por quê não simplesmente adicionar
código no construtor do bean ?
◦ O método de inicialização (init-method)
será invocado após a injeção de todas as
dependências do bean.
44. Ciclo de vida (3/6)
Interceptando a destruição de um bean;
Atributo destroy-method (local):
◦ <bean id=“…” class=“…” destroy-
method=“destroy” …
Atributo default-destroy-method (global):
◦ <beans default-destroy-method=“destroy” …
O método de destruição (destroy-method)
será invocado automaticamente pelo
framework Spring antes da destruição do
contexto da aplicação;
Este mecanismo deve ser utilizado para
liberação de recursos, por exemplo, para
liberação de pool de conexões ou para
liberar handlers para arquivos.
45. Ciclo de vida (4/6)
Exemplo:
◦ Iremos criar uma classe contento um
construtos, um método init e um método
destroy;
◦ A intenção desta classe é observar o ciclo
de vida de um bean dentro do contexto
de aplicação Spring.
46. Ciclo de vida (5/6)
Exemplo / classe:
Construtor
Método de
inicialização
Método de destruição
47. Ciclo de vida (6/6)
Exemplo / arquivo de configuração:
1
2
1 Método de inicialização.
2 Método de destruição.
Resultado da execução:
Foi criada uma instância
Dependência = null
Método de inicialização chamado
Dependência = Dependência injetada
49. Propriedades (2/25)
Valores padrão (tipos primitivos):
◦ Spring converte automaticamente de uma
representação textual (String) para o tipo
da propriedade, caso este seja um tipo
primitivo (boolean, int, double, etc);
◦ Utilização:
In-line:
<property name=“porta” value=“8080”/>
Aninhada:
<property name=“driver” >
<value>com.mysql.jdbc.Driver</value>
</property>
50. Propriedades (3/25)
Valores nulos (nulls):
◦ Elemento “null”:
<property name=“username” >
<null/>
</property>
◦ Atenção, um valor vazio é convertido para
“” (String vazio):
<property name=“username” >
<value/>
</property>
51. Propriedades (4/25)
Referências a outros beans:
◦ Nome da referência (definida no contexto):
Elemento idref:
<property name=“nomeRecurso”>
<idref bean=“beanRecurso”/>
</property>
O elemento idref foi criado como uma forma livre de
erros (pois a referência é validada quando o contexto é
carregado). Forma incorreta de obter o nome de uma
referência:
<property name=“nomeRecurso” value=“beanRecurso”/>
◦ Nome de uma referência local:
Definida no mesmo arquivo de configuração:
<property name=“nomeRecurso”>
<idref local=“beanRecurso”/>
</property>
52. Propriedades (5/25)
Referências a outros beans:
◦ Referência a um bean (definido no contexto):
Atributo ref (representação in-line):
<property name=“logger” ref=“log4j”/>
Elemento ref (representação aninhada):
<property name=“logger”>
<ref bean=“log4j”/>
</property>
◦ Referência a um bean local:
Definido no mesmo arquivo de configuração:
<property name=“logger”>
<ref local=“log4j”/>
</property>
53. Propriedades (6/25)
Tipos especiais:
◦ Apesar de Spring poder criar objetos de
qualquer classe, existem alguns tipos de
objetos em Java (ex: coleções e mapas)
que são bastante utilizados e que seria
interessante se houvesse uma forma de
instanciá-los e inicializá-los;
◦ Por esta razão, Spring provê uma série
de fábricas e elementos especiais com
este propósito.
54. Propriedades (7/25)
Tipos especiais / coleções:
◦ A definição de coleções utiliza as classes
do pacote
org.springframework.beans.factory.config;
◦ As fábricas responsáveis por criar
coleções, presentes neste pacote,
seguem a mesma convenção;
◦ Por exemplo, para criar uma lista nós
utilizaremos a classe ListFactoryBean,
existem também as classes
MapFactoryBean e SetFactoryBean.
57. Propriedades (10/25)
Tipos especiais / coleções – exemplo:
◦ Resultado da execução:
Janeiro
Fevereiro
Março
Abril
Maio
Junho
Julho
Agosto
Setembro
Outubro
Novembro
Dezembro
58. Propriedades (11/25)
Tipos especiais / coleções:
◦ A partir da especificação 2.0 do Spring,
criou-se alguns elementos especiais que
facilitam a tarefa de instanciar as
coleções. Estes elementos são:
list – definição de uma lista;
set – definição de um conjunto;
map – definição de um mapa;
props – definição de um objeto de
propriedades.
62. Propriedades (15/25)
Tipos especiais / coleções:
◦ Sintaxe do map:
Elemento principal:
map;
Elemento aninhado:
entry – representa uma dupla (chave, valor) de um
mapa:
Propriedades:
key (obrigatório) – chave do item armazenado no
map;
value (opcional) – valor armazenado no map;
value-ref (opcional) – referência a um bean
armazenado no map;
Elementos aninhados:
Valores possíveis padrão (ref. sintaxe do list).
65. Propriedades (18/25)
Tipos especiais / coleções:
◦ Exemplo de props:
◦ Observação:
Podem set atribuídos valores do tipo map para
atributos do tipo props (properties). Spring faz a
conversão automaticamente.
66. Propriedades (19/25)
Tipos especiais / coleções:
◦ Sintaxe do props:
Elemento principal:
props;
Elemento aninhado:
props – representa uma dupla (chave, valor) de um
objeto de propriedades (property):
Propriedades:
key (obrigatório) – chave do item armazenado no
map;
Elementos aninhados:
Valores literais;
null;
ref;
idref.
67. Propriedades (20/25)
Tipos especiais / coleções:
◦ Vimos como atribuir uma coleção (list,
set, map ou prop) diretamente a um valor:
◦ Porém, existem casos em que é
necessário reusar uma mesma coleção,
para isto foi desenvolvido o namespace
util com os seguintes elementos:
util:list;
util:set;
util:map;
util:set.
69. Propriedades (22/25)
Tipos especiais / contantes:
◦ A utilização de constantes na
implementação de sistemas de
informação é importante por melhorar a
legibilidade do código, eliminando os
“números mágicos”;
◦ Em Spring, no namespace util, existe um
elemento chamado util:constant
responsável por importar valores
constantes definidos nas classes.
70. Propriedades (23/25)
Tipos especiais / constantes:
◦ Exemplo:
1
1 Obtenção do valor da constante.
71. Propriedades (24/25)
Beans aninhados:
◦ Vimos anteriormente como atribuir
referências de beans à valores de
propriedades utilizando o elemento ref;
◦ Porém, caso não seja necessário
reutilizar o bean referenciado, poderemos
realizar esta atribuição de uma forma
mais compacta.
73. Templates e especialização
(1/7)
No desenvolvimento de um grande
sistema de informação é comum a
declaração de vários beans com
propriedades semelhantes;
Com a intenção de aumentar o reuso de
código, é possível transformar a
declaração de um bean em um template
e especializá-lo posteriormente,
alterando apenas o que for necessário;
Para isto, deve-se utilizar o atributo
parent na definição do bean.
78. Templates e especialização
(6/7)
Exemplo – arquivo de configuração:
1
2
1 Definição do template.
2 Especialização do template.
79. Templates e especialização
(7/7)
Beans abstratos:
◦ É possível que um template não
represente um bean que deva ser
instanciado, mas sim, apenas
especializado por outros beans;
◦ Neste caso, diz-se que este bean é
abstrato;
◦ Para explicitar que um bean é abstrato e
para proibir que ele seja instanciado,
deve-se utilizar o atributo abstract com o
valor true.
80. Mais de um arquivo de
configuração
Em sistemas muito grandes, com
vários módulos, não é prático manter
toda a configuração do sistema em
apenas um arquivo;
Uma boa prática é criar arquivos de
configuração separados por módulos
ou funcionalidades em comum;
Para isto, a plataforma Spring, define
alguns mecanismos que viabilizam
esta modularização.
81. Mais de um arquivo de
configuração
Conceitos básicos:
◦ Recursos;
◦ Importação de arquivos de configuração;
◦ Aliases.
82. Mais de um arquivo de
configuração
Recursos:
◦ Forma de referênciar arquivos através de
uma abstração semelhante à URLs;
◦ Tipos de recursos:
classpath – localiza o recurso utilizando o class
loader corrente;
file – localiza o recurso utilizando o sistema de
arquivos;
http – localiza o recurso utilizando uma conexão
http;
<vazio> – dependente do contexto, no caso do
XmlApplicationContext, busca os recursos no
mesmo diretório do arquivo de configuração;
◦ Exemplo:
classpath:/br/org/exemplo/applicationContext.xml
83. Mais de um arquivo de
configuração
Importação de arquivos de
configuração:
◦ Elemento import;
◦ Exemplo:
<import
resource=“classpath:/br/org/exemplo/applicationContext.x
ml”/>
84. Mais de um arquivo de
configuração
Aliases:
◦ Para reduzir o acoplamento entre dois
arquivos de configuração dependentes entre
si, é possível atribuir aliases (apelidos) para
os beans referenciados que foram definidos
em outros arquivos;
◦ Exemplo:
<alias name=“emailService” alias=“servicoEmail”/>
◦ No exemplo anterior, o bean declarado com
o id “emailService” passará a ser chamado
localmente pelo alias de “servicoEmail”.
Assim, se o nome mudar no arquivo original,
só será necessário alterar a definição do
alias.
85. Propriedades externas
As vezes é interessante separar
alguns valores de configuração em
arquivos de propriedade externos. Por
exemplo, configuração do acesso ao
banco de dados ou a configuração do
motor de log;
Para isto, no namespace context,
existe o elemento property-
placeholder;
Declaração do arquivo de
propriedades:
◦ <context:property-placeholder
87. Contexto de aplicação (1/4)
O contexto de aplicação (application context)
é responsável por instanciar os beans, injetar
dependências e realizar os processamentos
transversais (AOP) necessários;
Um contexto de aplicação deve implementar
a interface ApplicationContext;
O contexto de aplicação que é mais
comumente utilizado é:
◦ ClassPathXmlApplicationContext;
Porém a sua instanciação pode ser facilitada
para aplicações web utilizando um context
listener provido pelo framework Spring:
◦ ContextLoaderListener.
88. Contexto de aplicação (2/4)
ClassPathXmlApplicationContext:
◦ Utilização básica:
Construtor passando como parâmetro o
caminho, no classpath, para o carquivo de
configuração:
Nesta abordagem o arquivo de configuração
será localizado utilizando o ClassLoader
corrente.
89. Contexto de aplicação (3/4)
ContextLoaderListener:
◦ Configuração básica do web.xml:
◦ Na configuração básica, quando o contexto é
inicializado, o framework Spring procura o
arquivo applicationContext.xml no diretório
WEB-INF da aplicação web.
90. Contexto de aplicação (4/4)
web.xml:
◦ Definindo a localização do arquivo de
configuração no web.xml:
91. Anotações (1/8)
As anotações foram introduzidas no framework
Spring com a intenção de reduzir a quantidade
necessária de configuração;
As anotações básicas são:
◦ Component – anotação que define beans;
Service – anotação que define beans de serviço;
Repository – anotação que define beans de repositório;
◦ Autowired – anotação que define uma dependência;
Qualifier – responsável por cofigurar a injeção da
dependência;
◦ Aspect – anotação que define um aspecto (AOP);
◦ Além disto, Spring é compatível com as anotações
padrão (JSR-250) da plataforma JEE:
Resource – define uma dependência;
PostConstruct – define um método inicialização;
PreDestroy – define um método destruição.
92. Anotações (2/8)
Maiores detalhes sobre as anotações:
◦ Qualquer bean a ser disponibilizado no
contexto de aplicação pode ser marcado com
a anotação Component, porém existem
outras anotações derivadas (Service e
Repository) que servem para melhor
documentar a função dos beans além de
ajudar eventuais ferramentas que possam
interpretar/produzir código;
◦ Todas estas anotações possuem um atributo
opcional, chamado value, que serve para
definir um possível id para o bean.
93. Anotações (3/8)
A anotação Autowired deve ser aplicada em atributos
ou métodos “setter” de uma classe para indicar que ali
deve ser injetada uma dependência;
O único atributo desta anotação chama-se required,
que caso seja definido como “true” irá implicar no
lançamento de uma exceção se a dependência em
caso não coseguir ser resolvida;
Os valores para as dependências anotadas com a
anotação Autowired são resolvidas de duas formas:
◦ Por nome: tenta-se encontrar um bean com o id igual ao
nome da dependência;
◦ Por tipo: tenta-se encontrar um bean com o mesmo tipo da
dependência;
Atenção: caso a plataforma encontre mais de um valor
possível para a dependência, uma exceção será
lançada.
94. Anotações (4/8)
É possível definir qualificadores que
guiem o processo de injeção de
dependências;
Um qualificador é definido utilizando a
anotação Qualifier;
Esta anotação deve estar associada a
um atributo de um bean ou a um
parâmetro de um método “setter”;
Um qualificador possui um atributo
“value” que deve ser preenchido com
o id do bean que será injetado.
95. Anotações (5/8)
As anotações Aspect e derivadas servem para a
definição de aspectos, pontos de corte e
métodos interceptadores, de acordo com o
paradigma de programação orientada a aspectos
(AOP);
As anotações que compõem o módulo AOP de
Spring são:
◦ Aspect;
◦ Pointcut;
◦ Before;
◦ After;
◦ Aroud;
Mais a frente, na sessão reservada para
orientação a aspectos, estas anotações serão
detalhadas.
96. Anotações (6/8)
Anotações da JSR-250:
◦ O suporte às anotações definidas pela JSR-250 foi
incorporado à plataforma Spring, após a versão 2.5,
para que esta se tornasse compatível com a
especificação JEE 5.0;
Estas anotações são:
◦ Resource:
Tem função semelhante à anotação Autowired, serve para
indicar uma dependência. Possui um atributo opcional
name, que serve para especificar o nome do bean que será
injetado;
◦ PostConstruct:
Serve para definir um método como método de
inicialização no ciclo de vida do bean;
◦ PreDestroy:
Serve para definir um método como sendo um método de
destruição no ciclo de vida do bean.
97. Anotações (7/8)
Vamos reescrever o nosso primeiro
exemplo utilizando anotações;
Relembrando a arquitetura do
primeiro exemplo:
«Interface»
CalculaDivid
AlgoritmoJuro
a Associação s
Generalização
JurosComposto
JurosSimples
s
98. Anotações (8/8)
Baseado na arquitetura do primeiro
exemplo iremos anotar as classes
JurosSimples e JurosCompostos com a
anotação Service, pois tratam-se de
classes de serviço;
A classe CalculaDivida será anotada
com Component;
O atributo “algoritmo” da classe
CalculaDivida terá a anotação
Autowired;
Por fim o arquivo de configuração será
modificado para suportar as anotações.
103. Classe CalculaDivida JSR-
250
Podemos utilizar a anotação
Resource ao invés da Autowired:
Dica
◦ Se for injetar dependências por tipo,
prefira utilizar a anotação Autowired; caso
for utilizar injeção por nome, prefira
então, utilizar a anotação Resource.
104. Qualificadores personalizados
É possível criar qualificadores
personalizados de forma a melhorar a
legibilidade do código;
Exemplo:
◦ Criar os qualificadores chamados
DadosLocais e DadosRemotos, para
indicar que o acesso à dados realizado
pela dependência anotada deverá ser
realizado de forma local ou remota,
respectivamente.
105. Criando um qualificador
Para criar um qualificador, basta
definir uma anotação marcada com
@Qualifier, que tenha a mesma
retenção (Runtime) e que seja
aplicável (Target) aos mesmos
elementos (Field e Parameter);
Exemplo, o qualificador DadosLocais:
107. Associando os qualificadores
Para associar um qualificador a um
bean de serviço é necessário declarar
esta associação no arquivo de
configuração do Spring: 1
2
1 Classe do serviço.
2 Qualificador.
112. Qualificadores com atributos
Os qualificadores personalizados podem
ainda ter atributos associados. Eles
permitem ao programador especificar
ainda melhor como a injeção de
dependências será realizada;
Iremos criar um qualificador chamado
FilmeQualifier, que terá os atributos
gênero e formato;
Este qualificador servirá para decidir que
implementação de catálogo de filmes
utilizar baseado em seu gênero e
formato.
116. Persistência de dados
O framework Spring permite a
instanciação de objetos de qualquer
classe, porém, são providas algumas
funcionalidades que facilitam o a
implementação de persistência de
dados.
Iremos abordar as seguintes opções
para realização de persistência de
dados:
◦ Abstração JDBC do framework Spring;
◦ Spring + Hibernate;
◦ Spring + JPA.
117. Abstração JDBC Spring
Por quê uma nova abstração ?
◦ A equipe de desenvolvimento da plataforma
Spring sabe que apesar de JDBC ser uma
das bibliotecas Java mais simples e mais
utilizadas, ela ainda possui alguns problemas
e alguns pontos em que pode ser melhorada;
◦ Principalmente, a biblioteca JDBC não segue
muito bem as premissas de um projeto
orientado a objetos, além de não fornecer
um modelo uniformizado de exceções (cada
implementação de banco de dados possui as
suas exceções).
118. Abstração JDBC Spring
Vantagens:
◦ Definição centralizada dos parâmetros da
conexão com o banco de dados;
◦ Controle de abertura e encerramento de
conexões;
◦ Controle sobre os statements;
◦ Abstração mais alto nível de como iterar
sobre um conjunto de resultados
(resultset);
◦ Possibilidade de mapear linhas à objetos;
◦ Modelo unificado de exceções.
119. Requisitos básicos
Para utilizar a abstração JDBC Spring
é necessária a utilização de drivers
JDBC 2.0 ou 3.0 (para algumas
opções avançadas) e pelo menos
uma versão 1.4 da Java.
120. Exemplo simples
A forma mais fácil de utilizar o framework
JDBC Spring é:
◦ Sem connection pool:
Utilizar a classe DriverManagerDataSource para definir a
fonte de dados;
◦ Com connection pool:
Adicionar os jars (commons-dbcp.jar e commons-
pool.jar) do pacote Apache Commons DBCP ao projeto;
Utilizar a classe BasicDataSource para definir a fonte de
dados;
◦ Configurar uma fonte de dados (data source)
como um bean no arquivo de configuração do
Spring;
◦ Criar uma classe que extenda
SimpleJdbcDaoSupport, contendo os métodos
necessários para manipulação de dados.
122. Configuração da fonte de
dados
Sugestão:
◦ Utilizar um arquivo de propriedades para
guardar os atributos da conexão:
Arquivo jdbc.properties:
jdbc.driver=CLASSE_DO_DRIVER
jdbc.url=URL_DA_CONEXAO
jdbc.username=NOME_DO_USUARIO
jdbc.password=SENHA
◦ Exemplo de utilização:
123. Exemplo (1/10)
Criação de uma tabela para
armazenar contatos telefônicos
(dialeto MySQL):
CREATE TABLE CONTATO(
ID INTEGER NOT NULL AUTO_INCREMENT,
NOME VARCHAR(80) NOT NULL,
TELEFONE VARCHAR(20) NOT NULL,
PRIMARY KEY(ID)
)
124. Exemplo (2/10)
Criar um classe Contato para
representar as linhas da tabela criada
anteriormente:
125. Exemplo (3/10)
Definição de uma interface
(ContatoDAO) para acesso aos
dados:
126. Exemplo (4/10)
Criação de um DAO (Data Access
Object):
◦ Criar a classe ContatoDaoJdbc
extendendo SimpleJdbcDaoSupport:
◦ A classe SimpleJdbcDaoSupport define
um atributo do tipo JdbcTemplate que
pode ser acessado através do método
getJdbcTemplate;
◦ Este objeto permite a execução de
consultas, atualizações, remoções, etc;
127. Exemplo (5/10)
Definição dos scripts de consulta e
atualização da base de dados:
◦ Criar constantes para isolar estes scripts do
restante do código:
◦ Podemos observar que para este exemplo
iremos passar os parâmetros para os scripts
de forma posicional, ou seja, cada ‘?’ será
substituída por um parâmetro passado na
mesma ordem em que este aparecer no
script.
130. Exemplo (8/10)
Método de listagem:
Atenção para o row mapper criado:
◦ Esta pequena classe é responsável por
realizar o mapeamento objeto-relacional de
forma bastante simples.
133. Modelo de exceções
A abstração JDBC Spring provê um conjunto
de exceções de alto nível, independentes de
tecnologia de banco de dados, todas
extendendo a classe RuntimeException, ou
seja, não é obrigatório o tratamento de
exceções para os métodos desta abstração;
Desta forma o código tende a ficar mais
limpo e o tratamento de exceções mais
significativo;
Alguns exemplos destas exceções são:
◦ BadSqlGrammarException;
◦ TypeMismatchDataAccessException;
◦ PermissionDeniedDataAccessException.
134. Spring + Hibernate
Hibernate é o framework objeto-
relacional padrão de mercado;
Um utilizador pode simplesmente
instanciar uma SessionFactory
Hibernate no Spring utilizando sua
arquitetura de definição de beans;
Porém, Spring provê fábricas e
objetos utilitários que facilitam esta
tarefa.
135. Spring + Hibernate
Para utilizar Hibernate juntamente com
Spring é necessário copiar as bibliotecas
básicas do Hibernate além das outras
bibliotecas requeridas pelo framework (todas
contidas na distribuição do Hibernate);
De forma análoga à abordagem JDBC,
Spring provê uma classe chamada
HibernateDaoSupport que deve ser
extendida;
Esta classe disponibiliza um objeto do tipo
HibernateTemplate acessível através do
método getHibernateTemplate.
136. Spring + Hibernate
Modificaremos o exemplo anterior
para demonstrar a integração de
Spring com o Hibernate;
Para isto será necessário criar um
arquivo para definir a entidade
Contato (contato.hbm.xml), uma nova
classe ContatoDaoHibernate, por fim,
teremos que modificar o nosso
arquivo de configuração.
142. Spring + JPA
Da mesma forma que foi com
Hibernate, Spring provê fábricas e
classes utilitárias para auxiliar a
utilização de JPA;
Spring provê uma classe chamada
JpaDaoSupport que deve ser
extendida;
Esta classe disponibiliza um objeto do
tipo JpaTemplate acessível através do
método getJpaTemplate.
143. Spring + JPA
Modificaremos o exemplo anterior
para demonstrar a integração de
Spring com JPA;
Para isto será necessário criar um
arquivo para configuração do acesso
ao banco de dados (persistence.xml),
adicionar a anotação @Entity à classe
Contato, criar uma nova classe
ContatoDaoJpa, por fim, teremos que
modificar o nosso arquivo de
configuração do Spring.
149. Programação orientada a
aspectos
A programação orientada a aspectos,
ou simplesmente AOP, é um
paradigma que se propõe a separar
código de negócios de funções
“secundárias” e comuns à toda a
aplicação (aspectos);
Alguns exemplos de aspectos:
◦ Logging;
◦ Autenticação e autorização;
◦ Controle de transações.
150. Conceitos de AOP (1/2)
Spring utiliza AspectJ para implementar o
seu suporte a aspectos;
AspectJ possui alguns conceitos chave:
◦ Aspecto – conceito de algo a executar,
transversalmente a uma ou mais classes;
◦ Junção (joint point) – ponto na execução de um
programa (execução de um método ou
lançamento de uma exceção);
◦ Sugestão (advice) – ação tomada por um
aspecto em uma determinada junção;
◦ Introdução – inclusão de novos métodos ou
atributos em um tipo (classe ou interface);
◦ Objeto alvo – objeto sob sugestão de um ou
mais aspectos.
151. Conceitos de AOP (2/2)
Tipos de sugestões:
◦ Antes - ação a ser executada antes de uma
junção, porém, não tem o poder de evitar a sua
execução (a não ser que produza uma exceção);
◦ Depois/retorno - ação executada após o retorno
normal (sem ocorrência de exceções) de uma
junção;
◦ Depois/lançamento - ação executada caso uma
junção lance uma exceção;
◦ Depois/finally - ação executada independente
do retorno (normal ou com a ocorrência de
exceção) de uma junção;
◦ Em torno (around) - esta ação pode ser
executada antes e/ou depois de uma junção,
com ou sem exceções, e inclusive condicionar a
sua ocorrência.
152. Habilitando o suporte AOP
No arquivo de configuração Spring:
◦ <aop:aspectj-autoproxy/>
É necessário adicionar ao projeto à biblioteca
aspect4j (neste caso aspect4j-1.6.5.jar);
Declarando um aspecto:
◦ Um aspecto deve ser definido como uma classe,
anotada com @Aspect;
◦ Os aspectos podem ser explicitamente
declarados no arquivo de configuração, como
beans;
◦ Ou podem ser descobertos automaticamente
pelo motor de anotações do Spring:
<context:component-scan base-package=“…"/>
154. Expressões para definir
junções
Uma junção é definida por uma
expressão;
Toda expressão deve ser iniciada por um
designador:
◦ execution – execução de um método geral;
◦ within – limita a execução a alguns tipos
(normalmente a um pacote);
◦ this – limita a execução a um tipo específico
em relação ao proxy;
◦ target – limita a execução a um tipo
específico em relação ao tipo alvo;
◦ args – limita a execução à métodos com
determinados argumentos.
155. Exemplos
execution(public * *(..))
◦ Execução de todos os métodos públicos;
execution(* set*(..))
◦ Execução de todos os métodos iniciados em
“set”;
execution(*
pacote.Classe.*(..))
◦ Execução de todos os métodos da classe
“Classe” do pacote “pacote”;
within(pacote.*)
◦ Execução de todos os métodos de todas as
classes do pacote “pacote”.
156. Exemplos
within(pacote..*)
◦ Execução de todos os métodos de todas as
classes do pacote “pacote” e sub-pacotes;
this(pacote.Classe)
◦ Execução de todos os métodos da classe
“Classe” no pacote “Pacote”;
target(pacote.Classe)
◦ Execução de todos os métodos que invoquem os
métodos da classe “Classe” no pacote “Pacote”;
args(java.lang.String)
◦ Execução de todos os métodos que tenham
apenas um parâmetro, sendo este do tipo
“java.lang.String”.
157. Formato da expressão
execution
execution:
◦ modifiers-pattern? – private, protected,
public;
◦ ret-type-pattern – classe que chama o
método;
◦ declaring-type-pattern? – classe que declara
o método;
◦ name-pattern(param-pattern) – nome do
método e parâmetros;
◦ throws-pattern? – exceções lançadas pelo
método.
Os atributos que não forem opcionais,
podem ser generalizados com o símbolo
158. Adicionando o aspecto ao
exemplo
Arquivo de configuração:
Resultado da execução sobre o
exemplo anterior:
13/05/2009 01:54:12 aspectos.LoggerExemplo logAntes
INFO: Vai executar [listar]
13/05/2009 01:54:12 aspectos.LoggerExemplo logDepois
INFO: Executou [listar]
160. Exemplo
Transações declarativas;
Para utilizarmos o suporte a transações
declarativas que Spring provê, veremos
como utilizar aspectos diretamente no
arquivo de configuração:
<aop:config>
<aop:pointcut
id="fooServiceOperation"
expression="execution(* pkg.Classe.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut-ref="fooServiceOperation"/>
</aop:config>
161. Exemplo
Para definir transações
declarativamente é necessário
importar o namespace tx:
◦ xmlns:tx="http://www.springframework.org
/schema/tx"
◦ Para as seguintes localizações:
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spri
ng-tx-2.5.xsd
162. Exemplo
Definição do gestor de transações:
◦ DataSourceTransactionManager;
◦ Atributo obrigatório: dataSource;
◦ Associação do gestor de transações:
163. Spring MVC
Spring provê uma simples
implementação de um framework para
produção de páginas HTML e produção
de aplicações Web, chamado Spring
MVC;
O Spring MVC é baseado no framework
Struts, versão 1, porém possui algumas
vantagens, tais como:
◦ Qualquer classe (POJO) pode ser um
formulário (form);
◦ Qualquer classe (POJO) pode ser uma ação
(controller);
◦ Suporte a temas.
164. Spring MVC - Funcionamento
1 2
Usuário
(Navegador Controlador Controlado
Principal r
Model
)
o
6 3
Model
o
5 4
Template da
Visão
(JSP/XHTML
)
165. Configurando o ambiente
O controlador principal (Dispatcher
Servlet) deve ser configurado no arquivo
web.xml da sua aplicação web:
Neste caso, qualquer url terminada em
.form será direcionada para o dispatcher
servlet do Spring MVC.
166. Estudo de caso
Agora será implementada passo-a-
passo, em sala de aula, uma pequena
aplicação web utilizando Spring MVC;
Neste exercício serão demonstrados
os conceitos básicos de Spring MVC,
como criar uma aplicação simples
integrada com um banco de dados
relacional;
Tempo estimado do exercício:
◦ 3 horas.
167. Testes unitários
A plataforma Spring incentiva a
utilização de POJOs para a
construção de aplicações através da
utilização de composição;
Além disto, é possível obter um
contexto de aplicação simplesmente
referenciando o arquivo de
configuração do Spring;
Desta forma é bastante trivial a
construção de testes de unidade.
168. Tópicos avançados
Acesso a beans remotos (JNDI);
Transações;
Agendamento de tarefas;
Envio de e-mails;
WebServices;
JMS.