fj27 caelum spring

Upload: denis-marques

Post on 14-Jan-2016

274 views

Category:

Documents


60 download

TRANSCRIPT

  • 7/18/2019 FJ27 Caelum Spring

    1/98

    FJ-27

    Spring Framework

    n

    Ensino e Inovao

    C

    aelum www.caelum.com.br

  • 7/18/2019 FJ27 Caelum Spring

    2/98

    ri

    Caelum

    Ensino e inovao

    A Caelum atua no mercado com consultoria, desenvolvimento e ensino em computao. Sua equipe

    participou do desenvolvimento de projetos em vrios clientes e, aps apresentar os cursos de vero de Java

    na Universidade de So Paulo, passou a oferecer treinamentos para o mercado. Toda a equipe tem uma

    forte presena na comunidade atravs de eventos, artigos em diversas revistas, participao em muitos

    projetos open source

    como o VRaptor e o Stella e atuao nos fruns e listas de discusso como o GUJ.

    Com uma equipe de mais de 80 profissionais altamente qualificados e de destaque do mercado, oferece

    treinamentos em Java, Ruby on Rails e Scrum em suas trs unidades - So Paulo, Rio de Janeiro e

    Braslia. Mais de 8 mil alunos j buscaram qualificao nos treinamentos da Caelum tanto em nas unidades

    como nas prprias empresas com os cursos

    incompany.

    O compromisso da Caelum oferecer um treinamento de qualidade, com material constantemente

    atualizado, uma metodologia de ensino cuidadosamente desenvolvida e instrutores capacitados

    tecnicamente e didaticamente. E oferecer ainda servios de consultoria gil, mentoring e desenvolvimento

    de projetos sob medida para empresas.

    Comunidade

    Nossa equipe escreve constantemente artigos no

    Blog da Caelum

    que j conta

    com 150 artigos sobre vrios assuntos de Java, Rails e computao em geral.

    Visite-nos e assine nosso RSS:

    blog.caelum.com.br

    Acompanhe a Caelum no

    Twitter:

    twitter.com/caelum

    O

    GUJ

    maior frum de Java em lngua portuguesa, com 700 mil posts e 70 mil

    usurios. As pessoas da Caelum participam ativamente, participe tambm:

    .

    www.guj.com.br

    Assine nossa

    Newsletter para receber notcias tcnicas de Java, Rails, Agile e

    Web, alm de novidades, eventos e artigos:

    www.caelum.com.br/newsletter

    No site da Caelum h algumas de nossas Apostilas

    disponveis gratuitamente

    para download e alguns dos

    artigos

    de destaque que escrevemos:

    www.caelum.com.br/apostilas

    www.caelum.com.br/artigos

  • 7/18/2019 FJ27 Caelum Spring

    3/98

    ndice

    1

    Simplificando o desenvolvimento Enterprise

    1

    1.1 Por que Spring?

    1

    1.2 Sobre o curso FJ-27

    1

    1.3 Tirando dvidas

    2

    1.4

    Bibliografia

    2

    2 Injeo de dependncias e Inverso de Controle

    3

    2.1

    Nosso projeto

    3

    2.2

    Dependncias e o alto acoplamento

    4

    2.3

    Injeo de dependncias

    5

    2.4

    Inverso de controle e o princpio de hollywood

    7

    2.5 Para saber mais: Registry como alternativa a Dl

    7

    2.6 Para saber mais..

    8

    3

    Spring Framework

    9

    3.1

    O que ?

    9

    3.2 Arquitetura do Spring

    10

    3.3

    Introduo aos beans do Spring 12

    3.4 Configurando o Spring 12

    3.5

    Iniciando o container

    13

    3.6

    Injetando as Dependncias: por construtor e por setter

    13

    3.7

    Exerccios: Projeto com Spring IoC

    14

    3.8

    Exerccios opcionais: Injeco com Setter e Tipos Bsicos

    17

    3.9 Exerccios Opcionais: Valores Literais

    18

  • 7/18/2019 FJ27 Caelum Spring

    4/98

    4 Spring MVC

    21

    4.1 Spring MVC

    21

    4.2 Criando seu projeto web no Eclipse

    21

    4.3 Configurando o Spring MVC

    22

    4.4 View Resolvers

    22

    4.5 Seu primeiro Controller

    23

    4.6 Configurando

    23

    4.7 Exerccios: Nosso primeiro controller

    24

    4.8 Enviando dados para View

    24

    4.9 RequestMapping mais a fundo

    25

    4.10 O Controller de Produto

    26

    4.11 Gerenciamento e Injeo

    26

    4.12 Exerccios - Listando os Produtos

    27

    4.13 URLs amigveis

    28

    4.14 Melhor uso do HTTP

    28

    4.15 Exercicios: Melhor uso do http

    29

    4.16 Recebendo paramtros de Formulario

    30

    4.17 Forward X Redirect

    31

    4.18 Exerccios - Cadastro de Produto

    32

    4.19 Escopos

    32

    4.20 Web Escopos: Request, Session, Global Session

    33

    5 Integrando Spring, H ibernate e tecnologias de Persistncia

    35

    5.1 Introduo - Onde o Spring pode ajudar ao usar o Hibernate

    35

    5.2 Configurando o Hibernate no Spring

    35

    5.3 ProdutoHibernateDAO

    36

    5.4 @Repository

    37

    5.5 Exerccios

    37

    5.6 @Qualifier

    39

    5.7 Exerccios

    39

    5.8 No quero escolher um objeto, quero um padro

    39

    5.9 Exerccios

    40

    5.10 Transaes com Spring - Spring Transaction

    40

    5.11 Configurando o TransactionManager

    41

    ii

  • 7/18/2019 FJ27 Caelum Spring

    5/98

    5.12 Controle de Session com o Spring

    41

    5.13 Exerccios

    42

    5.14 Exerccios - Alterar Produtos

    43

    5.15 Exerccio Opcional: Remoo de produtos

    44

    5.16 Aumentando nosso domnio

    44

    5.17 Entitidade

    44

    5.18 Exerccios

    46

    5.19 Mostrando as movimentaes na tela

    49

    5.20 Exerccios

    49

    5.21 Lidando com LazylnitializationException

    50

    5.22 Soluo Open Session in View

    51

    5.23 Exerccios

    51

    5.24 Transaes Avanadas

    52

    5.25 Para saber mais: HibernateTemplate e outros Templates

    53

    6 Validao com Bean Validation

    55

    6.1 Introduo

    55

    6.2 Bean Validation

    55

    6.3 Hibernate Validator

    55

    6.4 Exerccios

    56

    6.5 Mostrando erros em tela

    57

    6.6 Exerccios

    58

    6.7 Customizando menssagens

    59

    6.8 Exerccio

    60

    7 Spring Security

    61

    7.1 Introduo ao Spring Security

    61

    7.2 Exerccios - Configurando o Spring Security

    62

    7.3 - Access Control List

    62

    7.4 Exerccios - Criando as classes de Domnio

    63

    7.5 Interfaces de Acesso

    64

    7.6 Exerccios - Suporte a Acesso de Dados

    67

    7.7 Login

    70

    7.8 Exerccios - Logando no Sistema

    71

    iii

  • 7/18/2019 FJ27 Caelum Spring

    6/98

    8 Apndice - AO P - Programao O rientada a Aspectos

    75

    8.1 Introduo a Programao Orientada a Aspectos

    75

    8.2 AOP na prtica

    76

    8.3 Elementos de um Aspecto

    77

    8.4 AOP com Spring

    77

    8.5 AOP no Spring com @AspectJ-style

    77

    8.6 Exerccios - AOP

    78

    8.7 Definindo Pointcuts e Advices

    79

    8.8 Exerccios

    81

    8.9 Outros Advices

    82

    8.10 Para saber mais: Combinando Pointcuts

    83

    8.11 Para saber mais: @Around

    84

    9 Apndice - Integrao entre Sistemas

    85

    9.1 Spring Integration

    85

    9.2 Exerccio: Spring Integration

    86

    10 Apndice - Enviando Email

    89

    10.1 Enviando E-mail com Spring

    89

    10.2 Exerccio: Spring Mail

    90

    Verso: 14.2.30

    iv

  • 7/18/2019 FJ27 Caelum Spring

    7/98

    CAPTULO

    1

    Simplificando o desenvolvimento Enterprise

    H duas formas de se construir o design de um software: Uma forma faz-lo to simples que obviamente

    no ter deficincias e a outra forma faz-lo to complicado que no ter deficincias bvias.

    C.A.R. Hoare, The 1980 ACM Turing Award Lecture

    1.1 - Por que Spring?

    Com suas ideias de um container leve, o Spring vem sendo apresentado h anos como uma alternativa mais

    simples arquitetura oficial do Java EE baseada em EJBs. J em 2008, a prpria SpringSource j mostrava

    que a oferta de empregos com Spring se equiparava a de EJB:

    http://bit.ly:springsourte-ejb

    E uma busca atualizada mostra que, de 2008 at hoje, a tendncia se manteve: a procura por Spring cresceu

    bastante e a de EJB continua estvel:

    http://bitly/jobtrends-Spring-ejb

    Como veremos, o princpio fundamental do Spring o uso de

    Injeo de Dependncias

    nos componentes

    da sua aplicao. Alm disso, prov um container com diversos servios j prontos para sua aplicao. Desde

    o surgimento do Spring, os princpios de

    Inverso de Controle e

    Injeo de Dependncias

    se tornaram funda-

    mentais em qualquer tipo de aplicao. Outros frameworks de injeo surgiram, como o Pico Container e o

    Google Guice, e at o prprio Java EE incorporou essas tcnicas em sua ltima verso com o

    CDI - Context

    and Dependency Injection.

    A importncia da injeo de dependncias hoje to grande que, em uma recente entrevista com os autores

    do livro

    Design Patterns

    em comemorao aos 15 anos do livro, Erich Gamma, um dos autores, disse que, se

    houvesse uma segunda edio do livro, um padro a ser includo seria

    Dependency Injection:

    http://bit .1y/entrevista-design-patterns

    1.2 - Sobre o curso FJ-27

    O curso FJ-27 foi reformulado com as novidades do Spring 3.x, a verso mais recente do framework. um

    curso focado nos principais conceitos do Spring, desde Inverso de Controle e Injeo de Dependncias at

    tpicos mais avanados como Orientao a Aspectos (AOP) e tecnologias como SpringMVC, REST e integrao

    com Hibernate e outros frameworks.

    Este um curso prtico, com muitos exerccios que abordam os tpicos discutidos em aula. Recomenda-

    mos fortemente que voc faa todos os exerccios e esclarea suas dvidas em aula. Foque seus estudos

    principalmente nos conceitos fundamentais.

    1

  • 7/18/2019 FJ27 Caelum Spring

    8/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    1.3 Tirando dvidas

    Para tirar dvidas dos exerccios, ou de Java em geral, recomendamos o frum do site do GUJ

    (http:

    -

    ww.guj.com.br

    ; ),

    onde sua dvida ser respondida prontamente.

    Fora isso, sinta-se vontade para entrar em contato com seu instrutor e tirar todas as dvidas que tiver

    durante o curso.

    1.4 - Bibliografia

    possvel aprender muitos dos detalhes e pontos no cobertos no curso em tutoriais na Internet em portais

    como o GUJ, em blogs (como o da Caelum:

    http:,' blog.caelum.com .br

    )

    e em muitos Sites especializados.

    Mas se voc deseja algum livro para expandir seus conhecimentos ou ter como guia de referncia, temos

    algumas indicaes dentre vrias possveis:

    Sobre Java e melhores prticas

    Refactoring, Martin Fowler

    Effective Java, Joshua Bloch

    Design Patterns, Erich Gamma et al

    Sobre o Spring Framework

    Spring in Action, Craig Walls e Ryan Breidenbach

    Referncia

    oficial: http:, static.springsource.org/spring/docs /3.0.x

    spring-frarnework-reference/html/

    Captulo 1 - Simplificando o desenvolvimento Enterprise - Tirando dvidas - Pgina 2

  • 7/18/2019 FJ27 Caelum Spring

    9/98

    CAPTULO

    2

    Injeo de dependncias e Inverso de

    Controle

    Se queres conversar comigo, define primeiro os termos que usas comigo

    Voltaire

    Nesse captulo, voc vai entender:

    o que Injeo de Dependncias e que problemas ela resolve;

    o que Inverso de Controle e tipos de inverses;

    como usar frameworks para satisfazer as dependncias do seu projeto.

    2.1 - Nosso projeto

    Ao longo do curso FJ-27, vamos desenvolver um sistema de controle de

    estoque de produtos.

    Vamos

    desenvolver desde seu modelo, sua persistncia, a camada Web, o controle de usurios e segurana. Tudo

    usando o

    Spring Framework

    e diversas de suas caractersticas.

    Vamos comear pensando na modelagem do domnio de negcio. Primeiro, temos a classe

    Produto:

    package br.com.caelum.estoque.model;

    public class Produto {

    private Long id;

    private String descricao;

    private Long quantidade;

    //getters e setters

    }

    Para persistirmos os produtos, usaremos o padro

    DAO.

    Nosso DAO ser modelado como uma interface

    Java. Desta forma, poderemos ter vrias implementaes do DAO e troc-las conforme necessrio.

    As operaes que teremos no

    ProdutoDAO:

    package br.com.caelum.estoque.dao;

    public interface ProdutoDAO {

    void salvar(Produto produto);

    void alterar(Produto produto);

    List listar();

    Produto buscarPorld(Long id);

    }

    3

  • 7/18/2019 FJ27 Caelum Spring

    10/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    No curso, ser particularmente interessante ter o DAO como interface, j que vamos ver Hibernate apenas

    mais pra frente. At l, para podermos criar nosso sistema usando persistncia, vamos criar uma implemen-

    tao simples do DAO em memria. Mais pra frente, vamos troc-la por uma implementao completa com

    Hibernate.

    Nosso

    ProdutoMemoriaDAO,

    por enquanto apenas com os mtodos de listagem e adio implementados:

    package br.com.caelum.estoque.dao;

    public class ProdutoMemoriaDA0 implements ProdutoDA0 {

    private List p rodutos = new ArrayList();

    public ProdutoMem oriaDA0() {

    Produto produto = new P roduto();

    produto.setDescricao("Mac Book");

    produto.setQuantidade(40);

    produtos.add(produto);

    }

    public L ist listar(){

    return produtos;

    }

    public void salvar(Produto produto) {

    produtos.add(produto);

    public Produto buscarPorld(Long id) {

    / / ainda no imp lementado

    return nu ll;

    }

    public void al terar(Produto prod uto) {

    / / ainda no imp lementado

    }

    }

    2.2 - Dependncias e o alto acoplamento

    Teremos tambm uma classe

    GerenciadorDeProduto

    responsvel por pedir dados de um

    Produto

    ao usurio,

    depois persistir esse objeto e por fim mostrar alguma confirmao.

    Se estivssemos na Web, seria equivalente a pegar os dados do request enviado por um formulrio, persistir

    e depois mostrar uma pgina

    de confirmao. Vamos ver a

    parte

    Web

    em um

    captulo

    mais

    a frente. Por

    enquanto, nossa classe

    GerenciadorDeProduto

    ser:

    Captulo 2 - Injeo de dependncias e Inverso de Controle - Dependncias e o alto acoplamento - Pgina 4

  • 7/18/2019 FJ27 Caelum Spring

    11/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    public class GerenciadorD eProduto {

    private ProdutoDAO produtoDao;

    public GerenciadorDeProduto() {

    this.produtoDao = new ProdutoMemoriaDA0();

    }

    public void novoProduto() {

    Produto produto = pedeD adosDoProdutoAoUsuario();

    this.produtoDao.salvar(produto);

    mostraConfirmacao();

    }

    }

    uma classe bastante simples. Ela apenas controla a execuo das coisas entre o modelo, o DAO e a

    interao com o usurio.

    Mas ela tem um problema. Nossa classe

    GerenciadorDeProduto

    est acoplada no s interface

    ProdutoDAO

    como implementao concreta

    ProdutoMemoriaDAO.

    Repare que o construtor conhece a imple-

    mentao especfica e d

    new na classe.

    Dizemos que a classe tem uma

    dependncia tanto com

    ProdutoDAO

    quanto com

    ProdutoMemoriaDAO.

    Mas, quando olhamos a lgica de negcios propriamente dita, no mtodo

    novoProduto,

    percebemos que

    o que realmente necessrio para execut-la

    algum DAO.

    A lgica em si no depende de qual instncia

    especificamente da implementao que estamos usando. (imagine, como ser nosso caso daqui a pouco, que

    tenhamos mais de uma implementao, como a

    ProdutoHibernateDAO)

    No fundo, precisamos ento apenas de

    algum

    ProdutoDAO

    mas acabamos tendo que dar

    new

    diretamente

    na implementao para us-la.

    Nossa aplicao resolve a implementao e a dependncia, chamando

    diretamente a classe especfica.

    O problema desse tipo de chamada que, no dia que precisarmos mudar a implementao do DAO, precisa-

    remos mudar nossa classe. Agora imagine que tenhamos 10 classes no sistema que usem nosso

    ProdutoDAO.

    Se todas do

    new

    na implementao especfica a ser usada (agora,

    ProdutoMemoriaDAO),

    quando formos mudar

    a implementao para, digamos,

    ProdutoHibernateDAO,

    precisaremos mudar em vrios lugares.

    E ainda ainda um segundo problema em gerenciar a dependncia diretamente na aplicao. Se a outra

    classe precisar de um processo de construo mais complicado, precisaremos nos preocupar com isso. Imagine

    a futura classe

    ProdutoHibernateDAD

    receba uma session do Hibernate. Ou ento uma

    ProdutoJDBCDAD

    que

    precise da conneotion. Se formos dar

    new

    nessas classes, precisaramos resolver essas exigncias que, se

    formos pensar bem, nem deveriam ser responsabilidades nossas.

    2.3 Injeo de dependncias

    O pattern

    Dependency Injection Dl) -

    Injeo de dependncias - procura resolver esses problemas. A

    ideia a classe no mais resolver suas dependncias por conta prpria mas apenas declarar que depende de

    alguma outra classe. E de alguma outra forma que no sabemos, algum resolver essa dependncia para ns.

    O cdigo da GerenciadorDeProduto

    fica com uma mudana sutil:

    Captulo 2 - Injeo de dependncias e Inverso de Controle - Injeo de dependncias - Pgina 5

  • 7/18/2019 FJ27 Caelum Spring

    12/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    public class GerenciadorDeProduto {

    private ProdutoDA0 produtoDao;

    public GerenciadorDeProduto(ProdutoDA0 produtoDao) {

    this.produtoDao = produtoDao;

    }

    public void novoProduto() {

    Produto produto = pedeDadosDoProdutoAoUsuario();

    this.produtoDao.salvar(produto);

    mostraConfirmacao();

    }

    }

    Repare que, agora, nossa classe no est mais acoplada implementao alguma do

    ProdutoDAO

    nem

    import

    do

    ProdutoMemoriaDA0

    existe mais. O que nossa classe diz que ela

    depende de algum ProdutoDAO

    sem acoplar-se a nenhuma implementao especfica e sem se preocupar em como resolver essa dependncia.

    Mas quem for usar essa minha classe, agora, vai precisar satisfazer as dependncias. Pode parecer que

    estamos apenas empurrando o problema, mas temos que olhar as classes isoladamente. Perceba que, do

    ponto de vista

    apenas da

    GerenciadorDeProduto,

    estamos recebendo nossas dependncias no construtor. Elas

    esto sendo

    injetadas

    para ns. Como isso vai acontecer de verdade no problema nosso.

    E, o melhor, imagine que o DAO em uso aquele do Hibernate. E que a classe

    ProdutoHibernateDA0

    tambm vai usar injeo de dependncias para recebera

    Session

    que ela precisa. Veja um esboo dessa

    classe:

    public class ProdutoHibernateDAO implements ProdutoDAO {

    private Session session;

    public ProdutoHibernateDAO(Session session) {

    this.session = session;

    }

    // implementacoes dos metodos com Hibernate, usando a Session

    }

    Aqui, temos dois pontos importantes. O primeiro que a classe

    ProdutoHibernateDA0

    est usando Dl para

    no precisar se preocupar em abrir uma session (um processo complicado). Mas, mais importante, lembrar da

    nossa

    GerenciadorDeProduto:

    magine ter que gerenciar nossa dependncia do DAO diretamente e ter que se

    preocupar no s com o

    ProdutoHibernateDA0

    como com a dependncia de session que ele tem. Precisaramos

    resolver as duas coisas, dando ainda mais trabalho.

    Contudo, como usamos Dl na classe

    GerenciadorDeProjeto,

    nem sabemos qual a implementao do DAO

    em uso e, muito menos, suas eventuais dependncias.

    Se gerenciar as prprias dependncias j ruim, o

    que dizer de gerenciar as dependncias das dependncias.

    Mas voltamos ao ponto de que, quem for usar a

    GerenciadorDeProjeto

    ter um imenso trabalho Ele ter

    que conhecer a

    GerenciadorDeProjeto,

    resolvera dependncia dela em

    ProdutoDAO, 0

    que, por sua vez, far

    ele conhecera implementao

    ProdutoHibernateDA0

    e ainda suas dependncias em

    Session,

    alm de saber

    como se cria uma Session. Parece muita coisa para uma classe s.

    a que entram em cena os

    Frameworks de Injeo de dependncia.

    Em projetos maiores, teremos

    muitas classes com muitas dependncias umas nas outras, tanto direta quanto indiretamente. Resolver esse

    complexo grafo de dependncias na mo possvel mas muito trabalhoso. Existem frameworks cujo objetivo

    resolver as dependncias.

    Captulo 2 - Injeo de dependncias e Inverso de Controle - Injeo de dependncias - Pgina 6

  • 7/18/2019 FJ27 Caelum Spring

    13/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Registramos nesses frameworks todas as nossas classes e deixamos a cargo dele resolver as interdepen-

    dncias entra elas. Nos preocupamos apenas em criar as classes usando o pattern de injeo de dependncias

    e em registrar as classes nos frameworks.

    E um dos frameworks mais importantes nessa parte de DI justo o

    Spring.

    2.4 - Inverso de controle e o princpio de hollyvvood

    Injeo de dependncia , na verdade, um modo de aplicar uma tcnica muito mais ampla chamada de

    Inverso de Controle (loC - Inversion of Control).

    A ideia principal de IoC inverter quem est no controle

    das invocaes no nosso cdigo.

    Lembre do nosso sistema: antes, ns invocvamos diretamente o construtor da

    ProdutoMemoriaDA0

    resol-

    vendo as dependncias manualmente. Ns controlvamos como e quando a criao do DAO aconteceria.

    Quando passamos a usar DI, invertemos o controle da criao desse DAO. Nossa classe no sabe mais

    nem como e nem quando a dependncia ser criada. Algum criar essa instncia e passar para ns. Usando

    Spring, o framework que passa a dar

    new

    nas nossas classes e no nossa aplicao diretamente.

    Isso inverter o controle. O framework passa a chamar as coisas para ns ao invs da nossa aplicao ser

    a responsvel por isso.

    H quem chame loC do

    Princpio de Hollywood.

    Dizem que h uma frase bastante famosa no mundo dos

    artistas de Hollywood que diz:

    "Don't call us; we call you" -

    ou

    No nos chame; ns te chamamos .

    a ideia

    do loC onde paramos de invocar os mtodos daquilo que precisamos e passamos a receber coisas prontas e a

    ser invocados pelo nosso framework.

    Dl uma forma de se fazer IoC mas no a nica. A ideia geral plugar o cdigo da aplicao em algum

    framework que far as invocaes certas e tudo funcionar. Alguns outros exemplos:

    Quando usamos uma

    HttpServlet,

    implementamos um mtodo

    doGet

    para tratar requisies Web. Mas

    no nos preocupamos em receber essas requisies e invocar o mtodo no momento certo. Apenas

    criamos nossa servlet, jogamos ela no container e ele invoca o mtodo para ns.

    Quando programamos para Desktop com Swing, frequentemente precisamos tratar eventos do usurio

    como, por exemplo, um clique. Ao invs de chamarmos um mtodo para saber se o clique for feito, no

    Swing, registramos um

    Listener

    e somos notificados do evento. Ou seja,

    o Swing invoca o mtodo do

    nosso listener no momento do clique sem precisarmos nos preocupar.

    Ao usar EJBs, s vezes precisamos saber, por exemplo, em que momento nosso objeto foi passivado. Po-

    demos saber isso implementando um mtodo de

    callback

    que ser invocado pelo container no momento

    da passivao. No EJB 2.x, usvamos o famoso

    ejbPassivate;

    no 3.x, podemos anotar qualquer mtodo

    COM @PrePassivate.

    H ainda outros exemplos onde invertemos o controle de invocao do nosso cdigo e deixamos a cargo de

    algum as chamadas no momento certo.

    2.5 - Para saber mais: Registry como alternativa a Dl

    Outra forma de obtermos a instncia de um

    ProdutoDAO

    sem precisar dar new

    diretamente e se acoplar com

    a implementao da interface utilizar o design pattern

    Registry.

    Muito utilizado at a verso 1.4 da J2EE, o

    Registry um padro de projeto que utiliza a soluo de registrar os recursos em um diretrio de componentes

    central - no EJB, era o famoso

    JNDI (Java Naming and Directory Interface).

    Assim, temos um lugar

    comum

    onde as classes podem obter referncias a outras classes.

    Captulo 2 - Injeo de dependncias e Inverso de Controle - Inverso de controle e o princpio de hollywood - Pgina 7

  • 7/18/2019 FJ27 Caelum Spring

    14/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    No exemplo, poderamos fazer a classe

    GerenciadorDeProduto

    obter uma referncia de

    ProdutoDAO

    por meio

    do Registry JNDI. Primeiro, precisamos registrara instncia do DAO que queremos (processo que chamado de

    bind). Geralmente isto feito pelo container J2EE utilizando arquivos de configurao

    (deployment descriptors)

    em um cdigo parecido com este:

    //Registra do DO no Registry

    Context ctx = new InitialContext();

    ctx.bind("produtoDao", new ProdutoMemoriaDA0());

    Nossa classe

    GerenciadorDeProduto

    pode, ento, obter uma referncia do tipo

    ProdutoDAO

    buscando no

    Registry JNDI pelo nome registrado. Este processo tem o nome de

    lookup:

    package br.com.caelum.fj27;

    public class GerenciadorDeProduto {

    private ProdutoDAO produtoDao;

    public GerenciadorDeProduto() {

    try{

    Context ctx = new InitialContext();

    produtoDao = (ProdutoDAO) ctx.lookup("produtoDao");

    } catch (NamingException ex) {

    // tratamento de exceo

    }

    }

    // outros metodos

    }

    Desta maneira, a inicializao do componente fica fora da classe

    GerenciadorDeProduto

    e, normalmente,

    pode ser feita atravs de arquivos de configurao. Mas, mesmo assim, o lookup da instncia de

    ProdutoDAO

    continuar na classe

    GerenciadorDeProduto.

    Ou

    seja, continuamos invocando algo e, portanto, isso no con-

    siderado Inverso de Controle. apenas mais uma forma de se evitar o acoplamento com as implementaes

    especficas das dependncias.

    2.6 - Para saber mais...

    Para saber mais sobre loC e DI, recomendamos a leitura dos artigos do Martin Fowler:

    http: //martinfowler.comiarticles/injection.html http: 'martinfowler.com/bliki' Inversion0fControl.html

    Captulo 2 - Injeo de dependncias e Inverso de Controle - Para saber mais... - Pgina 8

  • 7/18/2019 FJ27 Caelum Spring

    15/98

    CAPTULO

    3

    Spring Framework

    Homens sbios fazem provrbios, tolos os repetem

    Samuel Palmer

    Neste captulo, vamos ver o que o Spring Framework, qual sua arquitetura e qual seu princpio bsico de

    funcionamento.

    3.1

    - O que ?

    O Spring na verdade um

    framework de inverso de controle

    e no apenas de um framework de injeo

    de dependncias. Ele faz mais coisas que apenas resolver suas dependncias, um framework completo de

    servios para seus componentes.

    O

    Spring Framework

    um container leve

    (lightweight container),

    ou container de POJO's segundo o pes-

    soal do prprio Spring, com recursos de inverso de controle e orientao aspectos. O termo

    container

    usado pelo Spring, pois ele gerencia o ciclo de vida dos objetos configurados nele, assim como um container

    Java EE faz com os EJB's. Porm, considerado um container leve, pois ao contrrio do container Java

    EE em

    suas primeiras verses, ele no intrusivo e as classes da aplicao no possuem dependncias com o Spring.

    Alm disso, podemos dizer que o Spring tambm um framework de infraestrutura, pois prov servios

    como gerenciamento de transaes e de segurana, alm de se integrar com frameworks ORM. Com

    ele voc

    pode ter praticamente todos os benefcios de Java Enterprise Edition (JTA, JPA, JCA, Remoting, Servlets, JMS,

    JavaMail, JDBC, etc) mas sem utilizar EJB's.

    Container

    Podemos dizer que containers so programas utilizados para gerenciar componentes de uma apli-

    cao. Um exemplo de um container um container de servlets, onde sua funo gerenciar os

    componentes de interface web que conhecemos como Servlets e JSPs.

    Princpios do Spring

    O cdigo da aplicao no deve depender da

    API Spring;

    Spring no deve competir com boas solues j existentes no mercado, mas deve ser capaz de se integrar

    a elas;

    Teste de unidade uma tarefa crtica e o container no deve interferir neste objetivo.

    9

  • 7/18/2019 FJ27 Caelum Spring

    16/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Benefcios do Spring

    O container leve elimina a necessidade de cdigos repetitivos como lookups;

    Framework com inverso de controle da injeo de dependncia que resolve automaticamente as depen-

    dncias entre beans;

    Cdigo comum vrias sees, como gerenciamento de transaes, so implementados com AOP;

    Disponibiliza camadas de abstrao para outras tecnologias (como Hibernate, JPA, JDBC, JavaMail,

    Quartz, etc).

    3.2 - Arquitetura

    do Spring

    DAO

    Spring JDBC

    Transaction

    rnanngerrent

    ORM

    ~orneie

    JPA

    TopLirik

    JDo

    OJB

    iBatie

    JEE

    JMX

    JMS

    JCA

    Remoto1g

    EJBs

    Ernail

    Web

    Spring Web MVC

    Framework Integration

    Struts

    WetrWork

    Tapestr

    J$F

    Rich Wew Supporl

    JSPs

    Velocity

    FreeMarker

    PDF

    Jasper Repcds

    Excel

    Spring Portlet MVC

    OP

    Sprr

    OP

    sgectJ integr3tion

    Core

    The InC container

    Atualmente, o Spring est dividido em sete mdulos:

    Mdulo Core

    O mdulo principal o Core e representa as principais funcionalidades do Spring, como o container para

    inverso de controle e injeco de dependncias. Neste mdulo, o principal elemento a interface

    BeanFactory,

    que prov uma implementaco do factory pattern, removendo do sistema a necessidade de singletons e desa-

    coplando as dependncias de configuraces e especificaces da lgica de negcio do sistema.

    Os outros so mdulos de integrao com diversas outras tecnologias que o Spring suporta, tais como:

    Mdulo AOP

    Spring AOP

    Integrao com AspectJ

    Captulo 3 - Spring Framework - Arquitetura do Spring - Pgina 10

  • 7/18/2019 FJ27 Caelum Spring

    17/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Mdulo DAO

    Spring JDBC

    Gerenciamento de transaces

    Mdulo ORM

    Hibernate

    JPA

    TopLink

    JDO

    OJB

    iBatis

    Mdulo Java EE

    JMX

    JMS

    JCA

    Remoting

    EJBs

    Email

    Mdulo Web

    Spring Web MVC

    Integrao com Struts

    Integrao com WebWork

    Integrao com Tapestry

    Integrao com JSF

    Integrao com Rich View Support

    Integrao com JSPs

    Integrao com Velocity

    Integrao com FreeMaker

    Integrao com

    PDF

    Captulo 3 - Spring Framework - Arquitetura do Spring - Pgina 11

  • 7/18/2019 FJ27 Caelum Spring

    18/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Integrao com JasperReports

    Integrao com Excel

    Integrao com Spring Portlet MVC

    3.3 - Introduo aos beans do Spring

    Para entendermos o funcionamento do Spring, temos que entender o conceito de

    Bean

    que ele usa. Para o

    Spring, qualquer objeto da sua aplicao e que est sob o gerenciamento do Spring considerado um

    bean.

    Um bean

    nada mais do que uma classe Java que estar sob o gerenciamento do Spring, o container de

    loC/DI o responsvel pelo gerenciamento deste bean, bem como suas dependncias.

    3.4 - Configurando o Spring

    Configurando os beans

    As configuraes do Spring acontecem principalmente em um arquivo XML chamado

    applicationCon-

    text.xml.

    No Spring 2.5, foi adicionado o suporte a anotaes, mas muitas tarefas ainda precisam do XML

    e ele ainda usado em muitos projetos. Por isso, vamos primeiro ver como fazer as configuraes dos nossos

    beans via XML antes de ver a abordagem com anotaes.

    Veja a configurao de um bean no XML do Spring:

    Tag beans

    A tag

    o elemento root do nosso arquivo XML. Dentro dela teremos as tags

    que representam

    a configurao dos objetos do nosso sistema na forma de bean para o Spring.

    Na tag

    ,

    temos duas propriedades principais:

    id -

    representa o identificador do nosso bean, o Spring no aceita id's repetidos;

    class -

    representa o FQN da nossa classe.

    FQN

    FQN significa

    FuIIy-Qualified Name,

    ou nome completo de uma classe. O FQN de uma classe

    o nome da classe com o seu pacote completo. Por exemplo, o FQN da classe object

    j ava . lang . Obj ect ,

    o FQN da interface List

    j ava util Li st.

    Captulo 3 - Spring Framew ork - Introduo aos beans do Spring - Pgina 12

  • 7/18/2019 FJ27 Caelum Spring

    19/98

    Caelum - http://www.caelum.com.br

    Spring Framework 3

    3.5 Iniciando o container

    Aps feita a configurao dos nossos

    beans

    no Spring, precisamos iniciar o container de IoC. Esta iniciali-

    zao muito simples e pode ser feita de diversas formas. Quando trabalhamos dentro de um container Web

    com algum framework MVC, essa inicializao costuma ser automtica com apenas algumas configuraes.

    Mas quando estamos trabalhando direto no

    main,

    sem container, precisamos iniciar o Spring explicitamente.

    Podemos fazer isso usando a classe

    ApplicationContext:

    ApplicationContext context =

    new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

    Criado o contexto do Spring, podemos pedir uma instncia de qualquer bean registrado l. Invocando o

    framework diretamente, basta passar o id do componente:

    ProdutoDA0 dao = (ProdutoDA0) context.getBean("produtoDao");

    A partir da verso 3 do Spring podemos utilizar um segundo parmetro do mtodo

    getBean

    para definir o

    tipo do bean. Assim nem preciso fazer o cast:

    ProdutoDA0 dao = context.getBean("produtoDao", ProdutoDao.class);

    Tambm podemos descobrir o bean apenas pelo tipo (e no pela id):

    ProdutoDA0 dao = context.getBean(ProdutoDao.class);

    No exemplo acima deve existir apenas um bean compatvel com a interface

    ProdutoDao.

    Caso contrrio o

    Spring cria um exceo.

    3 C -

    injetando as Dependncias: por construtor e por setter

    Como vimos anteriormente, um dos principais recursos do Spring o gerenciamento automtico das depen-

    dncias dos beans. Mas, por padro, a amarrao

    (wiring)

    das dependncias no feita de forma automtica.

    Por isso, somos obrigados a configur-las uma por uma no arquivo XML.

    Para fazermos essa a amarrao das dependncias com o Spring, temos duas opes: por construtor ou

    por mtodos

    setter.

    Injetando dependncia por construtor

    Na classe

    GerenciadorDeProduto

    que fizemos antes, declaramos a dependncia com

    ProdutoDA0

    no cons-

    trutor. a forma comumente preferida hoje em dia e o Spring a suporta sem problemas.

    Captulo 3 - Spring Framework - Iniciando o container - Pgina 13

  • 7/18/2019 FJ27 Caelum Spring

    20/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Injetando dependncia por setter

    Poderamos ter escrito nossa classe

    GerenciadorDeProduto

    para receber a instncia do DAO que ela precisa

    atravs de um mtodo

    setProdutoDao

    ao invs de receber no construtor.

    Essa foi a forma preferida e incentivada no Spring durante muito tempo. No XML, a configurao um pouco

    diferehte:

    lmport

    Selecione

    General, Existing Projects into workspace.

    Clique Next

    Selecione

    Archive File

    e indique o arquivo

    /caelum/zips/27/fj27-projeto-spring.zip

    2)

    Crie a classe

    Produto no pacote

    br.com.caelum. estoque:

    package br.com.caelum.estoque;

    public class Produto {

    private Long id;

    private String descricao;

    private Integer quantidade;

    //getters e setters

    }

    3)

    Crie a interface ProdutoDAO no pacote

    br . com. caelum. estoque . dao

    Captulo 3 - Spring Framework - Exerccios: Projeto com Spring loC - Pgina 14

  • 7/18/2019 FJ27 Caelum Spring

    21/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    package br.com.caelum.estoque.dao;

    public interface ProdutoDA0 {

    void salvar(Produto produto);

    void alterar(Produto produto);

    List listar();

    Produto buscarPorld(Long id);

    }

    4)

    Como ainda no vimos a integrao do Spring com Hibernate e nosso objetivo focar no Spring por en-

    quanto, vamos criar uma implementao de DAO bem simples que apenas adiciona os produtos em uma

    lista em memria.

    Crie a classe

    ProdutoMemoriaDAO

    no pacote

    br. com. caelum.estoque.dao

    com a implementao simples do

    DAO em memria. Ainda no implementaremos o mtodo de alterao:

    package br.com.caelum.estoque.dao;

    public class ProdutoMemoriaDA0 implements ProdutoDA0 {

    private List produtos = new ArrayList();

    public List listar(){

    return produtos;

    }

    public void salvar(Produto produto) {

    produtos.add(produto);

    }

    public Produto buscarPorld(Long id) {

    return produtos.get(id.intValue() - 1);

    }

    public void alterar(Produto produto) {

    }

    }

    5)

    Vamos criar agora nossa classe

    GerenciadorDeProduto.

    Mais tarde, vamos transform-la em um componente

    de um sistema Web usando Spring MVC. Por isso, vamos faz-la um pouco diferente da que vimos antes.

    Ao invs de mostrar uma mensagem de confirmao para o usurio, vamos apenas retornar uma String de

    confirmao para ele. E o objeto

    Produto

    que pediramos para o usurio preencher com os dados, vamos

    receber como argumento no mtodo.

    Crie a classe

    GerenciadorDeProduto

    no pacote

    br. com. caelum.estoque:

    Captulo 3 - Spring Framew ork - Exerccios:

    Projeto

    com Spring IoC - Pgina 15

  • 7/18/2019 FJ27 Caelum Spring

    22/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    package br.com.caelum.estoque;

    public class GerenciadorDeProduto {

    private ProdutoDA0 produtoDao;

    public GerenciadorDeProduto(ProdutoDAO produtoDao) {

    this.produtoDao = produtoDao;

    }

    public void novoProduto(Produto produto) {

    System.out.println("Salvando Produto.");

    this.produtoDao.salvar(produto);

    }

    public List getProdutos(){

    return produtoDao.listar();

    }

    }

    Repare que, como estamos usando

    DI,

    declaramos a dependncia com o

    DAO

    no construtor.

    6) Falta agora criar toda a configurao do Spring com os beans que acabamos de fazer.

    a)

    Abra o arquivo chamado

    applicationContext.xml

    que se encontra no diretrio

    src

    do seu projeto. Este

    o arquivo de configurao do Spring.

    b)

    Coloque a configurao entre a tag

    :

    7) Para testarmos a injeo dos componentes que temos at agora, vamos utilizar uma classe simples com

    mtodo main chamada

    Testelnjecao, que j existe em seu projeto.

    Nela, criamos o

    Appl icat ionContext

    do Spring e, logo em seguida, pediremos uma instncia do nosso

    gerenciador de produtos. Queremos obter essa instncia sem precisar satisfazer as dependncias dela.

    Abra a classe

    Testalnjecao

    que est no pacote

    br. com. caelum. estoque:

    Captulo 3 - Spring Framework - E xerccios: Projeto com Spring loC - Pgina 16

  • 7/18/2019 FJ27 Caelum Spring

    23/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    package br.com.caelum.estoque;

    public class Testalnjecao {

    public static void main (String[] args) {

    // cria o contexto do Spring

    ApplicationContext context =

    new ClassPathXmlApplicationContext("applicationContext.xml");

    // obtm o gerenciador

    GerenciadorDeProduto gerenciador =

    context.getBean("gerenciadorProduto", GerenciadorDeProduto.class);

    // cria um Produto como se o usurio tivesse preenchido um formulrio

    Produto produto = new Produto();

    produto.setDescricao("Livro Spring in Action");

    produto.setQuantidade(10);

    // chama a lgica e v o resultado

    gerenciador.novoProduto(produto);

    // verifica que o produto foi adicionao ao nosso dao em memoria

    for (Produto p : gerenciador.getProdutos()) {

    System.out.println("Descricao: " + p.getDescricao());

    System.out.println("Quantidade: " + p.getQuantidade());

    }

    }

    }

    Execute essa classe como um programa Java e veja o resultado.

    3.8 - Exerccios opcionais: Injeco com Setter e Tipos Bsicos

    1)

    Vamos agora na nossa classe

    GerenciadorDeProduto

    njetar o ProdutoDAO

    atravs do

    setter

    Na classe

    GerenciadorDeProduto

    comente o construtor e gere um setter para receber o

    ProdutoDAO:

    public class GerenciadorDeProduto {

    private ProdutoDAO produtoDao;

    //comente o construtor e gere o setter

    public void setProdutoDAO(ProdutoDAO produtoDao)

    this.produtoDao = produtoDao;

    }

    public String novoProduto(Produto produto) {

    this.produtoDao.salvar(produto);

    return "salvo";

    }

    public List getProdutos() {

    return produtoDao.listar();

    }

    }

    Repare que ainda estamos usando DI, mas declaramos agora a dependncia no setter.

    2)

    Falta alterar a configurao do Spring para definir a injeo pelo setter.

    Captulo 3 - Spring Framework - Exerccios opcionais: Injeco com Setter e Tipos Bsicos - Pgina 17

  • 7/18/2019 FJ27 Caelum Spring

    24/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    a)

    Procure a declarao do bean

    gerenciadorProduto

    no arquivo

    applicationContext.xml.

    b)

    Tire a injeo pelo construtor, coloque a pelo setter:

  • 7/18/2019 FJ27 Caelum Spring

    25/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Jose

    Joao

    4) Vamos criar uma classe para testar as injees:

    rie a classe

    Testelnjecao2

    no pacote

    br.com.caelum.estoque .

    1

    public class Testelnjecao2 {

    2

    3

    4

    public static void main(String[] args) {

    5

    ApplicationContext applicationContext =

    6

    new ClassPathXmlApplicationContext("applicationContext.xml");

    7

    SpringBean springBean =

    8

    (SpringBean) applicationContext.getBean("springBean");

    9

    19 if (springBea n = null) {

    11

    12

    System .out.println("instanciado ");

    13

    System.out.println(springBean.getNome());

    14

    System.out.println(springBean.getQuantidade());

    15

    System.out.println(springBean.getPropriedades().get("cidade"));

    16

    17

    for (String string : springBean.getNomesO) {

    18

    System.out.println(string);

    19

    20

    21

    22 }

    Rode a classe e verifique na sada do console que todas os atributos foram injetados pelo Spring.

    Captulo 3 - Spring Framework - Exerccios Opcionais: Valores

    Literais - Pgina 19

  • 7/18/2019 FJ27 Caelum Spring

    26/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Captulo 3 - Spring Framework - Exerccios Opcionais: Valores Literais - Pgina 20

  • 7/18/2019 FJ27 Caelum Spring

    27/98

    CAPTULO

    4

    Spring MVC

    O verdadeiro discpulo aquele que supera o mestre.

    Aristteles

    4.1 - Spring MVC

    O padro de projeto MVC a forma mais utilizada para o desenvolvimento de aplicaes Web. A diviso

    entre as camadas

    Model

    e View

    atravs do intermedirio

    Controller

    simplifica a evoluo da aplicao e tambm

    a manuteno de cdigo existente.

    Existem vrias implementaes de frameworks MVC no mercado. Entre os mais famosas temos o

    JavaSer-

    ver Faces

    e o Struts.

    Nos mdulos do Spring, encontramos tambm um framework MVC que traz aos desenvol-

    vedores as vantagens citadas acima, mas tambm, integrao simples com os outros servios de infraestrutura

    do Spring, como DI, AOP e Transaes.

    4.2 - Criando seu projeto web no Eclipse

    Vamos importar um novo projeto para nosso Eclipse

    com toda a estrutura de um projeto Web j pronto. Alm

    disso, os jars do Spring e as classes que fizemos at agora tambm sero includas.

    Vamos usar como container Web o Apache Tomcat 6, que pode ser baixado em

    http: torncat.apache.org

    Instalando e configurando o Tomcat

    Entre na pasta

    caelum

    no seu Desktop e v na pasta

    21

    D dois cliques para abrir o arquivo

    apache-tomcat-6.x.x.zip

    Clique em

    Extract e selecione o

    Desktop

    Volte ao Eclipse e Clique com o boto direito na aba

    Server

    Selecione New -> Server

    Adicione um Servidor da pasta

    Apache Tomcat

    verso 6.X

    Clique em Finish

    Inicie

    o Tomcat pelo cone da barra de ferramentas

    21

  • 7/18/2019 FJ27 Caelum Spring

    28/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Importando o projeto

    V em

    File -> lmport

    Selecione

    General, Existing Projects into workspace.

    Clique Next

    Selecione

    Archive File

    e indique o arquivo

    /caelum/zips/27/fj27-projeto-mvc.zip

    D start no Tomcat e teste a url

    http: localhost:8080 estoque

    4.3 - Configurando o Spring MVC

    O Spring MVC foi desenvolvido com base na classe

    org. springframework.web. servlet .DispatcherServlet

    que um

    Servlet

    que trata as requisies, redirecionamentos e outras funes que facilitam o uso do framework.

    Como todo

    Servlet,

    precisamos configur-lo no

    web.xml

    da aplicao. Na configurao do

    DispatchServlet

    importante lembrar de informar o diretrio onde est o XML com as configuraes dos beans que o Spring vai

    gerenciar, esse diretrio indicado atravs do parmetro

    contextConf igLocation.

    Veja como fica o trecho do

    web.xml

    com a configurao:

    Spring MVC Dispatcher Servlet

    org.springframework.web.servlet.DispatcherServlet

    contextConfigLocation

    /WEB-INF/spring/app-config.xml

    1

    Spring MVC Dispatcher Servlet

    *.html

    4.4 View Resolvers

    No XML de configurao do Spring necessrio registrar o

    ViewResolver,

    que tem como objetivo inte-

    grar

    Controller e

    View, deixando-os desacoplados. Com

    o View Resolver, podemos utilizar vrias tecnologias

    diferentes com nossos controllers. Por exemplo, JSP, Velocity ou XSLT.

    Na configurao do bean, podemos dizer o

    pref ix

    e suff ix de onde estaro nossas views. Quando um

    Controller executado, ele devolve o nome da View que deve ser renderizada para

    DispatchServlet.

    Ela por

    sua vez passa o nome para o

    ViewResolver

    que descobre a view concatenando o nome retornado ao

    pref ix

    e

    suff ix configurados.

    Vamos usar a seguinte configurao:

  • 7/18/2019 FJ27 Caelum Spring

    29/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Nesta configurao, se o Controller devolvesse, por exemplo, a string "index", o

    ViewResolver

    procuraria a

    seguinte view para renderizar "WEB-INF/views/index.jsp".

    4.5 - Seu primeiro Controller

    A partir do Spring 2.5, possvel utilizar anotaes para a configurao dos Controllers. Essas anotaes

    trouxeram muitos benefcios para a utilizao do Spring MVC como a simplicidade de configurao de objetos

    para representar a camada Controller.

    Entre as anotaes que o Spring MVC disponibiliza, temos a @Controller que indica que o Bean deve ser

    gerenciado. E a anotao

    @RequestMapping

    que informa a URL de acesso ao devido mtodo no controller.

    Usando essas duas anotaes para criar um controller teramos:

    package br.com.caelum.fj27.exemplo;

    @Controller

    public class MundoC ontroller {

    @RequestMapping("ola")

    pub lic String executar {

    System.out.println("Executando o Controller");

    return "ok"

    }

    }

    Para executar o exemplo acima, basta chamar a

    URL

    da aplicao terminando em

    /ola. Ex: http:

    localhost:8080 spring

    ola.htinl

    O mtodo anotado com

    @RequestMapping,

    no tem restrio quanto a sua assinatura. A opo de retornar

    uma String utilizada para informar qual view deve ser renderizada aps a execuo do mtodo.

    No exemplo anterior, a view renderizada se chama

    ok

    e ter seu diretrio e extenso informadas pelo

    ViewResolver.

    Por exemplo:

    WEB-INF/views/ok.jsp.

    4.6 - Configurando

    A anotao @Controller no lida por default. O Spring sempre usa o XML como padro e para usarmos

    classes anotadas, temos que configurar o XML do Spring com a seguinte instruo:

    Com isso, o Spring vai reconhecer as classes anotadas com @Controller.

    Alm do elemento para reconhecer as anotaes @Controller, precisamos informar qual o pacote o Spring

    deve rastrear os componentes anotados:

    Lembrando que necessrio configurar o namespace corretamente.

  • 7/18/2019 FJ27 Caelum Spring

    30/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    xmlns:context="http://www.springframework.org/schema/context

    "

    xmlns:mvc="http://www.springframework.org/schema/mvc

    "

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.0.xsd

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

    ">

    4.7 - Exerccios: Nosso primeiro controller

    1)

    Vamos agora, criar a classe

    ProdutosController

    no pacote

    br.com.caelum.estoque.controller.

    Iremos

    tambm anot-la com @Controller para que o Spring MVC possa reconhec-la.

    package br.com.caelum.estoque.controller;

    //importa

    @Controller

    public class ProdutosCo ntroller {

    @RequestMapping("index")

    publ ic Str ing index() {

    return "produ tos/index";

    }

    }

    2)

    Configure o XML do Spring para habilitar o suporte a anotao @Controller e informar onde o spring

    deve procurar por beans anotados. Adicione as seguintes linhas ao seu

    app-config.xml

    no diretrio WEB-

    INF/spring/app-config.xml:

    3)

    Falta criar nossa

    View.

    Crie uma pasta chamada produtos em

    WEB-INF/views/ e, dentro, uma JSP cha-

    mada index.jsp

    com o seguinte contedo de teste:

    Spring MVC

    4)

    Inicie o servidor e acesse seu controller chamando a URL http://localhost:8080

    /estoque /index.html

    4.8 - Enviando dados para View

    Os controllers do Spring podem enviar dados para as view renderizadas. Os mtodos do

    Controller que iro

    devolver dados a tela, devem declarar

    ModelAndView como seu tipo de retorno.

    O objeto

    ModelAndView

    carrega a informao da view a ser renderizada e tambm dos dados que devem ser

    disponibilizados na view. Exemplo:

    Captulo 4 - Spring MVC - Exerccios: Nosso primeiro controller - Pgina 24

  • 7/18/2019 FJ27 Caelum Spring

    31/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    @Controller

    public class ProdutosController {

    @RequestMapping("listarProdutos")

    public ModelAndView listar(){

    List produtos = new ArrayList();

    Produto macBook = new Produto();

    macBook.setDescricao("Mac Book");

    macBook.setQuantidade(100);

    Produto ipad = new Produto();

    ipad.setDescricao("IPad");

    ipad.setQuantidade(200);

    produtos.add(macBook);

    produtos.add(ipad)

    ModelAndView modelAndView = new ModelAndView("produto/lista");

    modelAndView.addObject(produtos);

    return modelAndView;

    }

    }

    Acessamos o

    ProdutosController

    pela URL

    littp://localhost:8080/estoque, produtos listarProdutos.html

    . Na execuo do mtodo listar(), criamos uma lista contendo alguns produtos. Depois, criamos um objeto

    mod.elAndview e passamos no construtor a pgina de retorno

    lista

    que fica dentro do diretrio

    produto "WEB-

    INF/views/produto/lista.jsp".

    Nossa lista de produtos ento adicionada no objeto

    ModelAndView

    e o mtodo termina retornando o objeto

    modelAndView.

    Agora, podemos acessar a lista de produtos na JSP usando

    Expression Language.

    importante sabe qual

    o nome que usamos para o acesso de nossa lista de produtos. O Spring utiliza uma conveno para isso. No

    nosso exemplo, acessaramos da seguinte maneira na JSP:

    ${produto.descricao} -

    ${produto.quantidade}

    O nome

    produtoList

    gerado pelo Spring devido ao nosso

    List

    ser declarado com um tipo genrico Produto:

    List.

    Se tivermos um List de String - List

    -

    , a forma de acesso seria -

    ${stringList}

    4.9 - RequestMapping mais a fundo

    @RequestMapping

    permite o mapeamento de urls por

    Controller. Por exemplo, podemos mapear um controller

    para

    /produtos

    e ento para o acesso a qualquer mtodo mapeado dentro do controller seria necessrio a

    chamada

    a URL

    da classe anteriormente. Ex:

    Captulo 4 - Spring MVC - RequestMapping mais a fundo - Pgina 25

  • 7/18/2019 FJ27 Caelum Spring

    32/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/listar")

    public ModelAndView listar(){

    //.

    .

    }

    @RequestMapping(value="/salvar")

    public String salvar(){

    }

    }

    Para acessar o mtodo

    listar

    )

    de

    ProdutosController

    precisamos chamar a seguinte a url que nosso

    controller foi mapeado

    /produtos

    e ento a url do mtodo

    /listar. Ex:

    http:f locadhost:8080/estoque/produtos

    listar.html

    4.10 - O Controller de Produto

    O Controller

    de Produto vai acessar a camada DAO que, no momento, representada com dados em

    memria. O mtodo

    listar

    ) de

    ProdutoMemoriaDAO

    retornar uma lista com todos os produtos cadastrados.

    O

    Controller

    deve obter esses dados e disponibiliz-los para o view que ento vai list-los em tela.

    4.11 - Gerenciamento e Injeo

    No ltimo capitulo, mapeamos a classe

    ProdutoMemoriaDAO

    e informamos que ela era uma dependncia de

    GerenciadorDeProduto

    no XML. O Spring tambm prov a configurao de componentes e suas dependncias

    fazendo o uso de anotaes. Ento vamos configurar

    ProdutoMemoriaDAO

    como um componente para poder

    injeta-la como dependncia de

    ProdutosController.

    A anotao @component deve ser utilizada para configurar objetos que o Spring deve gerenciar em seu

    container.

    package br.com.caelum.dao;

    @Component

    public class ProdutoMemoriaDAO implements ProdutoDA0 {

    // . .

    }

    Essa anotao equivalente a seguinte linha de XML:

    A anotao

    @Autowired

    deve ser utilizada para indicar uma dependncia e que a mesma deve ter seu valor

    injetado.

    @Controller

    public class ProdutosController {

    @Autowired

    private ProdutoDA0 produtoDAO;

    }

    Captulo 4 - Spring MVC - O Controller de Produto - Pgina 26

  • 7/18/2019 FJ27 Caelum Spring

    33/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    S podemos injetar beans gerenciados em outros beans tambm gerenciados. No exemplo acima injetamos

    O ProdutoDAO

    no

    ProdutosController

    porque ambos so gerenciados pelo o Spring as anotaes @component e

    @Controller tem como objetivo o mesmo, sendo informar o Spring que ele deve gerenciar aqueles objetos.

    4.12 - Exerccios - Listando os Produtos

    1)

    Adicione a anotao @ component na sua classe

    ProdutoMemoriaDAO.

    @Component

    public class ProdutoMemoriaDAO implements ProdutoDAO {

    }

    2)

    Vamos criar o mtodo que vai listar os produtos em nossa classe

    ProdutosController.

    O mtodo listar()

    vai fazer uma chamada ao ProdutoDAO que vai ser injetado pelo Spring e adicionar seu resultado no objeto

    ModelAndVlew.

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @Autowired

    private ProdutoDAO produtoDAO;

    // metodo ndex()

    @RequestMapping(value="/listar")

    public ModelAndView listar() {

    ModelAndView modelAndView = new ModelAndView("produtos/lista");

    modelAndView.addObject(produtoDAO.listar());

    return modelAndView;

    }

    }

    3)

    Crie um JSP chamado Iista.jsp

    dentro do diretrio "WEB-INF/views/produtos/lista.jsp" para mostrar os pro-

    dutos que so disponibilizados pela chamada do mtodo listar() de

    ProdutosController.

    Lista Produtos

  • 7/18/2019 FJ27 Caelum Spring

    34/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    4.1:3 URLsanugavels

    @RequestMapping

    pode ser usada tambm para criao de urls bonitinhas. Supondo que temos o

    ProdutosController

    e ele tem um mtodo que deve listar um produto especifico de determinado

    id.

    O m-

    todo poderia ter a seguinte estrutura:

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/listar")

    public ModelAndView listar(Long id){

    //

    }

    }

    E poderamos executar o mtodo atravs da url "/produtos/listar?idade=22" o parmetro idade seria passado

    ao listar )

    que por sua vez filtraria o produto por seu

    id

    e ento devolveria para a View.

    Ultimamente um recurso muito utilizado na web so as urls amigveis, que so urls mais legveis ao usurios.

    Poderamos implementar nosso mtodo dessa forma:

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/listar/{id}")

    public ModelAndView listar(@PathVariable Long id){

    //..

    }

    }

    Agora podemos executar nosso mtodo atravs da seguinte url "produtos/listar/22" e assim o mtodo

    listar )

    seria executado, o Spring por sua vez iria verificar que informamos que um valor vindo na url se-

    ria uma varivel {id} e que informamos que o mesmo iria ser passado ao mtodo

    @PathVariable

    4

    .

    14 -

    ,,,Melh9r, uso do HTTP

    O uso dos verbos do http corretamente muito importante trazem benefcios para nossa aplicao. O

    GET

    por exemplo, tem como objetivo buscar informaes e por isso seus parmetros so passados na url. Se

    utilizarmos isso de maneira correta os usurios da aplicao podem se beneficiar para fazer o bookmark de

    url de relatrios. Como as informaes vo por parmetros de url, eles podem chama-las todas as vezes sem

    problemas e tambm passar para que outras pessoas vejam o mesmo relatrio. Podemos informar ao Spring

    que devido mtodo s pode ser acessado por um determinado verbo. Ex:

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/listar/{id}", method=RequestMethod.GET)

    public ModelAndView listar(@PathVariable Long id){

    //

    }

    }

    Captulo 4 - Spring MVC - URLs amigveis - Pgina 28

  • 7/18/2019 FJ27 Caelum Spring

    35/98

    Caelumhttp://www.caelum.com.br

    Spring Framework 3

    Se tentarmos acessar a url "/produtos/listar/22" utilizando um formulrio com o verbo

    POST

    o spring no

    permitira devido a uri ser ligada a utilizao do verbo

    GET.

    4.15 - Exercicios: Melhor uso do http

    1)

    Vamos criar o mtodo

    mostrar()

    em ProdutosController.

    Nele vamos usar o recurso de Url Friendly e

    receber o id do

    Produto

    detalhado na url. Iremos tambm colocar ambos mtodos

    mostrar()

    e listar()

    para apenas responderem ao verbo GET do http porque ambos so utilizados para pesquisa.

    package br.com.caelum.estoque.dao;

    / / im ports

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosC ontrol ler {

    @Autowired

    private ProdutoDA0 produtoDAO ;

    / /metodo index()

    @RequestMapping(value="/listar", method=RequestMethod.GET)

    public Mo delAndV iew listar() {

    ModelAndView modelAndView = new ModelAndView("produtos/lista");

    modelAndView.addObject(produtoDAO.listar());

    return modelAndView;

    }

    @RequestMapping(value="/mostrar/{id}" , method=RequestMethod.GET)

    public ModelAndView m ostrar(@PathVariable Long id){

    ModelAndView m odelAndView = new M odelAndView("produtos/mostrar");

    modelAndView.addObject(produtoDAO.buscarPorId(id));

    return modelAndView;

    }

    2)

    Precisamos tambm, criar a jsp que vai mostrar o

    Produto

    detalho. O nome da jsp

    mostrar

    e deve ser

    criada no diretrio

    "WEB-INF/views/produtos".

    D etalhes do Produto

    Id :

    Descricao :

    Quantidade :

    3)

    A listagem de produtos deve ser alterada para ter um link que vai chamar o mtodo mostrar, para o

    Produto

    ser detalhado.

    Captulo

    4 -

    Spring MVC - Exercicios: Melhor uso do http - Pgina 29

  • 7/18/2019 FJ27 Caelum Spring

    36/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Lista Produtos

    ${produto.descricao} - ${produto.quantidade} -

    detalhes

    4) Reinicie o servidor de aplicao e teste a pgina de detalhes.

    4.16 - Receben do paranttros de. Forrnulario

    Um grande poder dos frameworks MVC atuais a capacidade de converter dados em texto passados como

    parmetros via HTTP para objetos do nosso domnio. Se temos o seguinte bean:

    public class Produto {

    private Long id;

    private String descricao;

    private Integer quantidade;

    // get e set

    }

    O Controller que tem que receber o objeto do tipo

    Produto

    como parmetro para o mtodo, deve declarar no

    parmetro do mtodo que vai ser chamado.

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosController{

    @RequestMapping(value="/salvar")

    public String salvar(Produto produto){

    System.out.println(produto.getDescricao());

    System.out.println(produto.getQuantidade());

    return "ok";

    }

    }

    O formulrio HTML, que vai fazer a requisio ao mtodo

    salvar () deve passar os parmetros que devem

    ser setados no parmetro do mtodo. O nome dos parmetros sendo enviado devem seguir o nome do conjunto

    de getters e setters do parmetro do mtodo sendo chamado. No nosso exemplo, o parmetro seria o

    Produto

    e os getters e setters seriam para as propriedades descricao

    e quantidade.

    Captulo 4 - Spring MVC - Recebendo paramtros de Formulario - Pgina 30

  • 7/18/2019 FJ27 Caelum Spring

    37/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Quando a requisio feita pela URL http:,./localhost:8080/estoque/produtos/salvar.html o mtodo

    salvar()

    de

    ProdutosController

    executado. O Spring MVC verifica que esse mtodo recebe um parme-

    tro que do tipo Produto.

    Ento o Spring MVC procura na requisio parmetros que tenham o nome de

    alguma das propriedades do bean.

    No exemplo acima, so enviados os parmetros

    descricao

    e

    quantidade.

    O Spring ento verifica que nosso

    bean

    Produto

    tem duas propriedades com o mesmo nome. Lembrando que propriedades em Java o conjunto

    get e set para um atributo, no exemplo

    getDescricao(), setDescricao()

    e

    getQuantidade(), setQua_ntidade().

    4.17 Forward X Redirect

    Toda execuo de mtodo em algum

    Controller

    pode devolver String

    ou ModelAndView

    que informam qual

    view deve ser renderizada. Podemos tambm no dizer o nome de uma view mas a url de outro mtodo em um

    Controller.

    Por exemplo:

    @Controlller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/index")

    public String index(){

    return "produtos/listar.html"

    }

    @RequestMapping(value="/listar")

    public ModelAndView listar(){

    //....

    }

    No exemplo acima ao chamar /index

    o Spring faz o foward para /produtos/listar

    executando ento o mtodo

    listar O. O forward o comportamento padro do spring mas podemos tambm fazer o

    redirect da ao.

    @Controlller

    @RequestMapping(value="/produtos")

    public class ProdutosController {

    @RequestMapping(value="/index")

    public String index(){

    return "redirect:produtos/listar.html"

    }

    @RequestMapping(value="/listar")

    public ModelAndView listar(){

    //

    }

    }

    Captulo 4 -

    Spring MVC - Forward X Redirect - Pgina 31

  • 7/18/2019 FJ27 Caelum Spring

    38/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    4.18 Exerccios Cadastro de Produto

    1)

    Crie a jsp

    form.jsp

    no diretrio "WEB-INF/views/produtos" para o cadastro de produtos.

    Cadastro de Produtos

  • 7/18/2019 FJ27 Caelum Spring

    39/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Escopo Singleton

    O escopo do tipo

    singleton

    define que ser criado uma nica instncia do bean para todas requisies

    recebidas pelo Spring para aquele bean. O Spring garante que esta instncia ser nica para cada instncia

    do loC container do Spring. Se tivermos um nico

    BeanFactory

    ou

    ApplicationContext,

    teremos uma nica

    instncia de um bean do tipo

    singleton. singleton

    o padro.

    Escopo Prototype

    O escopo do tipo

    prototype

    define que ser criada uma nova instncia do bean para cada requisio recebida

    pelo Spring para aquele bean.

    4.20 Web Escopos: Request, Session, Global Session

    Alm dos escopos

    singleton

    e

    prototype,

    o Spring disponibiliza mais trs escopos de uso especfico em

    aplicaes web:

    request, session e

    global session.

    Escopo Request

    O escopo do tipo

    request

    define que o ciclo de vida do bean ser atrelado a um Request HTTP. O Spring

    garante que cada request possui sua prpria instncia do bean. Ao final do request, o objeto descartado.

    Escopo Session

    O escopo do tipo

    session

    gerencia o ciclo de vida do bean baseado na

    HttpSession

    do usurio.

    Escopo Global Session

    O escopo do tipo

    global session

    gerencia o ciclo de vida do bean baseado na

    HttpSession

    do usurio. Este

    escopo semelhante ao escopo de

    session

    visto anteriormente, com a diferena que ele pode ser lido em

    outros contexto para aplicao que usam a tecnologia de Portlets.

    Captulo 4 - Spring MVC - Web Escopos: Request, Session, Global Session - Pgina 33

  • 7/18/2019 FJ27 Caelum Spring

    40/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Captulo 4 - Spring MVC - Web Escopos: Request, Session, Global Session - Pgina 34

  • 7/18/2019 FJ27 Caelum Spring

    41/98

    CAPTULO

    5

    Integrando Spring, Hibernate e tecnologias

    de Persistncia

    5.1 - Introduo - Onde o Spring pode ajudar ao usar o Hibernate

    Dentre as diversas caractersticas do Spring uma das que mais chama a ateno a integrao nativa com

    diversas tecnologias importantes do mercado, dentre eles est o

    hibernate,

    a principal ferramenta ORM para

    Java.

    Mas como o Spring ajuda a trabalhar com o Hibernate?

    De diversas maneiras A primeira delas atravs da principal funcionalidade do Spring, o controle de

    objetos. O Spring pode controlar a abertura e fechamento da

    SessionFactory

    do Hibernate, com isso

    todos

    os

    componentes do Spring podem receber como dependncia a SessionFactory, agora, controlada pelo Spring.

    Outra parte importante do Spring o controle transacional que ele oferece. Ao delegar o controle da Ses-

    sionFactory para o Spring, ele consegue abrir e fechar transaes de maneira automtica, de maneira muito

    parecida com o JTA.

    Alm de se integrar ao Hibernate o Spring tambm pode se integrar JPA, JDBC e outras ferramentas de

    persistncia.

    5.2 - Configurando o Hibernate no Spring

    Para funcionar a integrao com o Hibernate o Spring disponibiliza uma

    Factory Bean

    para a SessionFactory

    do Hibernate. Utilizando esta

    factory

    fazemos com que a SessionFactory

    do hibernate seja gerenciada pelo

    Spring.

    AnnotationSessionFactoryBean

    A

    Factory Bean

    que o

    Spring possui a

    org. springframework.orm.hibernate3.annotation.AnnotationSessionFac

    Esta classe deve ser configurada como um bean do Spring em seu xml de configurao.

    A classe

    AnnotationSessionFactoryBean

    nos permite configurar todas as propriedades do Hibernate dire-

    tamente no arquivo do Spring, no necessitando o uso do arquivo de configurao do prprio do Hibernate

    hibernate.cfg.xml.

    jdbc:mysql://localhost/fj27

    com.mysql.jdbc.Driver

  • 7/18/2019 FJ27 Caelum Spring

    42/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    true

    org.hibernate.dialect.MySQLDialect

    true

    true

    update

    br.com.caelum.estoque.model.Produto

    Ao integrarmos o Hibernate ao Spring, a configurao do Hibernate, que antes era feita separadamente,

    passa a ser feita diretamente no Spring. Isso necessrio para deixarmos o Spring gerenciar a criaco da

    SessionFactory

    do Hibernate permitindo assim que o Spring faa a injeco automtica da sessionFactory do

    Hibernate.

    destroy-method

    A propriedade

    destroy

    method

    da tag

    bean

    o nome do mtodo que ser invocado sempre que o

    Spring finalizar o ciclo de vida da nossa

    SessionFactory.

    hibernate.cfg.xml

    Ao invs de configurar o hibernate direto no Spring, podemos manter o arquivo hibernate.cfg.xml

    separado e apenas referenci-lo no Spring:

    classpath:location_of_config_file/hibernate.cfg.xml

    5.3 - ProdutoHibernateDA0

    Agora podemos criar um novo DAO que realmente acesse o banco de dados. Para isso basta pedir para

    o Spring injetar uma

    SessionFactory

    em alguma classe. Lembrando que o Spring injeta apenas beans geren-

    ciados em outros tambm gerenciados, para isso devemos declarar que nosso DAO deve ser gerenciado pelo

    Spring anotando-o com @component.

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - ProdutoHibernateDAO - Pgina 36

  • 7/18/2019 FJ27 Caelum Spring

    43/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    @Component

    public class ProdutoHibernateDA0 implements ProdutoDA0 {

    private Session session;

    @Autowired

    public ProdutoHibernateDAO(SessionFactory factory) {

    session = factory.openSession();

    }

    public List listar(){

    List produtos = session.createQuery("from Produto").list();

    return produtos;

    }

    public void salvar(Produto produto) {

    session.save(produto);

    }

    public Produto buscar(Long id) {

    return session.get(Produto.class, id);

    }

    public void alterar(Produto produto) {

    session.update(produto);

    }

    }

    5A

    -

    @Repository

    Anteriormente comentamos que as anotaes

    wontroner

    e

    @Component

    tinham o mesmo objetivo, indicar

    ao Spring que os beans anotados devem ser gerenciados e que a diferena entre as mesmas era apenas

    semntica. Para o caso dos DAOs temos a mesma situao, podemos anotar nossos DAOs com

    @Repository,

    ela ter o mesmo efeito da @Component.

    5.5

    -

    Exerccios

    1) Faa o mapeamento da classe Produto.

    package br.com.caelum.estoque;

    @Entity

    public class Produto {

    @Id

    @GeneratedValue

    private Long id;

    private String descricao;

    private Integer quantidade;

    //getters e setters

    }

    2)

    Abra o arquivo

    app-config.xml

    no diretrio "WEB-INF/spring", e adicione as seguintes

    linhas

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - @Repository - Pgina 37

  • 7/18/2019 FJ27 Caelum Spring

    44/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    jdbc:mysql://localhost/fj27

    com.mysql.jdbc.Driver

    root

    org.hibernate.dialect.MySQLDialect

    true

    true

    update

    true

    br.com.caelum.estoque.Produto

    3)

    Crie a classe

    ProdutoHibernateDAD

    no pacote

    br . com. caelum. estoque . dao:

    @Repository

    public class ProdutoHibernateDAO implements ProdutoDAO {

    private Session session;

    @Autowired

    public ProdutoHibernateDAO(SessionFactory factory) {

    session = factory.openSession();

    }

    public List listar(){

    List produtos =

    session.createQuery("from Produto").11st();

    return produtos;

    }

    public void salvar(Produto produto) {

    session.save(produto);

    }

    public Produto buscarPorld(Long id) {

    return (Produto) session.get(Produto.class, id);

    }

    public void alterar(Produto produto) {

    session.update(produto);

    }

    4)

    Reinicie o servidor e tente fazer o cadastro de algum produto.

    No funcionar.

    Leia a exceo e sua causa

    raiz

    (root

    cause .

    O que aconteceu?

    Capitulo 5 - Integrando Spring, Hibernate e

    tecnologias de Persistncia - Exerccios - Pgina 38

  • 7/18/2019 FJ27 Caelum Spring

    45/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    5.6 @Qualifier

    Ao testar o sistema o Spring lanou uma exeo na nosso console. Isso aconteceu porque o Spring descobre

    o que injetar nos

    beans

    atravs do

    tipo

    do objeto a ser injetado. No nosso caso o Spring tenta injetar algum

    bean

    que implemente a interface

    ProdutoDAO, porm

    existem duas implementaes, a

    ProdutoMemoriaDAO

    e a

    ProdutoHibernateDAO,

    com isso o Spring se perde na hora de fazer a injeo.

    Neste nosso caso poderamos simplesmente apagar a

    ProdutoMemoriaDA0

    que resolveria o problema, po-

    rm em cenrios que realmente devam existir duas implementaes devemos especificar qual delas queremos

    receber como injeo. exatamente esse o objetivo da anotao

    @Qualifier.

    Com o

    @Qualifier

    podemos especificar atravs do id do bean

    qual implementao queremos receber.

    public class ProdutoC ontroller {

    @Autowired

    Nualifier("produtoHibernateDAO")

    private ProdutoDAO produtoDAO;

    / /cdigo antigo

    }

    Indicamos o nome

    produtoHibernateDAO

    porque o Spring configura o id dos

    beans

    anotados atravs do

    nome da classe. A sua politica se o nome no foi passado diretamente via uma das anotaes

    @Controller

    , @Component

    e @Repository

    ele simplesmente coloca o nome da classe anotada transformando a primeira letra

    do nome em minuscula. Neste caso

    ProdutoHibernateDAO

    fica produtoHibernateDAO.

    Fora a facilidade proporcionada pelo Spring, tambm tiramos proveito do uso do polimorfismo, que permitiu

    uma troca tranquila da implementao.

    5.7 - Exerccios

    1) Altere sua classe controler para receber o

    ProdutoHibernateDAO

    ao invs do

    ProdutoMemoriaDA0

    @Controller

    @RequestMapping(value="/produtos")

    public class ProdutosC ontroller {

    @Autowired

    @Qualifier("produtoHibernateDA0")

    private ProdutoDAO produtoDAO;

    / /cdigo antigo

    }

    2) Cadastre alguns produtos.

    5.8 - No quero escolher um objeto, quero um padro

    Embora possamos resolver a ambiguidade da injeo atravs do @Qualifier, muitas vezes um

    bean

    muito

    mais injetado que o outro. Nesse cenrio o Spring oferece uma anotao que marca um bean como sendo o

    padro a ser injetado a @Pr imary.

    Caso no seja usado nenhum

    @Qualifier

    o bean anotado com @Primary

    ser

    o injetado.

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - @Qualifier - Pgina 39

  • 7/18/2019 FJ27 Caelum Spring

    46/98

    Caelum - http://www.caelum.com.br

    Spring Framework 3

    Exefcidlos

    1)

    Anote a classe

    ProdutoHibernateDA0

    COM

    @Primary:

    @Repository

    @Primary

    public class ProdutoHibernateDA0 implements ProdutoDA 0{

    //codigo ja existente

    }

    2)

    Retire o

    @Qualifier do atributo

    produtoDAO da classe

    ProdutoController,

    deixando apenas a anotao

    @Autowired:

    public class ProdutoController{

    @Autowired

    ProdutoDAO produtoDAO;

    }

    5.10 - Transaes com Spring Spring Transaction

    Alm do gerenciamento da

    SessionFactory o

    Spring tambm pode controlar a abertura e fechamento de

    transaes.

    O controle de transao pode ser feito via xml ou via anotao.

    O

    mais simples via anotao, porm, por motivos de referncia segue abaixo um exemplo de como o

    controle de transao pode ser feito via xml:

  • 7/18/2019 FJ27 Caelum Spring

    47/98

    ri Caelum

    http://www.caelum.com.br

    Spring Framework 3

    @Repository

    @Transactional

    public class ProdutoHibernateDAO implements ProdutoDA0 {

    //codigo

    }

    Porm at o momento nosso sistema no fez o uso de transaes. O hibernate est configurado com o

    autocommit ativado, dando commit em todas nossas operaes automaticamente. Tambm temos que lembrar

    que o tipo de tabela utilizada no MySQL no da suporte a transaes e por isso apenas o flush do autocommit

    basta para os dados serem persistidos.

    O MySQL tem dois tipos de tabela, Mylsam e InnoDB. Mylsam que a

    default

    no Ubuntu, no oferece

    suporte a transaes e por isso no tivemos problemas at o momento. Para testarmos o controle de transaes

    vamos alterar o tipo de tabela do MySQL, mudando o dialeto do Hibernate.

    Alterar:

    org.hibernate.dialect.MySQLDialect

    Para :

    org.hibernate.dialect.MySQL5InnoDBDialect

    E tambm remover a linha do autocommit:

    true

    5.11 - Configurando o TransactionManager

    Para o suporte a transao ser ativado precisamos fazer duas configuraes no xml do Spring.

    A primeira habilitar o gerenciador de transao. Porm como o controle do Spring pode ser para JPA,

    Hibernate, JDBC e outros, devemos configurar o gerenciador exatamente para uma dessas tecnologias. No

    caso do hibernate a nica dependncia que o TransactionManager precisa uma

    SessionFactory.

  • 7/18/2019 FJ27 Caelum Spring

    48/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    @Repository

    @Transactional

    public class ProdutoHibernateDA0 implements ProdutoDAO {

    private SessionFactory sessionFactory;

    @Autowired

    public ProdutoHibernateDAO(SessionFactory factory) {

    this.sessionFactory = factory;

    }

    public void salvar(Produto produto) {

    this.sessionFactory.getCurrentSession().save(produto);

    }

    //outros metodos

    }

    Obter a

    session

    atravs do

    getCurrentSession

    o recomendado pela documentao do Spring.

    5

    1

    ; EEm?nclicicns

    1)

    Altere o arquivo

    app

    -

    conf ig xml

    para que o dialeto do MySQL seja

    InnoDB

    e com isso tenhamos suporte s

    transaes com o banco de dados manualmente:

    org.hibernate.dialect.MySQL5InnoDBDialect

    2)

    Delete a linha que configura o autocommit:

    true

    3)

    Tente cadastrar um produto novo

    Entre no MySQL para conferir a insero do dado:

    Abra o terminal do Linux

    digite o comando

    mysql -u root

    agora dispare um select na tabela de Produtos

    use fj27;

    select * from Produto;

    Repare que o produto no est l

    Tabelas antigas

    Se o produto foi inserido, provavelmente porque a tabela ainda est no formato

    MyISAM, mude-a

    para

    InnoDB

    com o comando: alter table Produto type=innodb;

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - Exerccios - Pgina 42

  • 7/18/2019 FJ27 Caelum Spring

    49/98

    Caelum http://www.caelum.com.br

    Spring Framework

    3

    4)

    Adicione as seguintes linhas ao seu app-config.xml:

  • 7/18/2019 FJ27 Caelum Spring

    50/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    ${produto.descricao} - ${produto.quantidade} -

    detalhes

    - editar

    3)

    Crie a jsp editar.jsp

    no diretrio "WEB

    -

    INF/views/produtos/"

    Alterar Produto


    Descricao:

    Quantidade:

    4)

    Reinicie o servidor e altere algum produto.

    5.15 - Exerccio Opcional: Remoo de produtos

    1) Para deixar o sistema mais completo, desenvolva a funcionalidade de remoo dos produtos.

    5.16 - Aumentando nosso dornnio

    Nosso sistema de controle de estoque at o momento est bem simples. Apenas cadastrando, listando e

    alterando produtos. Vamos adicionar agora o conceito de Movimentao. Uma movimentao deve ser gerada

    para todas as operaes realizadas no estoque, ou seja, se aumentarmos a quantidade de produtos em estoque.

    geramos uma movimentao de entrada, caso diminua, geramos uma movimentao de sada.

    5.17 - Entitidade

    Devido ao nosso novo problema vamos adicionar ao nosso projeto a entidade de movimentacao. Ele vai

    representar as movimentaes realizadas. Entre seus atributos temos a data que foi efetuada, a quantidade do

    produto que foi alterada, o tipo da movimentacao que pode ser ENTRADA ou SAIDA e um relacionamento ao

    Produto em questo.

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - Exerccio Opcional: Remoo de produtos - Pgina 44

  • 7/18/2019 FJ27 Caelum Spring

    51/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    package br.com.caelum.estoque;

    @Entity

    public class Movim entacao {

    @Id

    @GeneratedValue

    private Long id;

    private C alendar data;

    @Enumerated(EnumType.STRING)

    private TipoMovimentacao tipo;

    private Integer quan tidade;

    @ManyToOne

    private Produto produto;

    //getters e setters

    }

    Para facilitar o trabalho, o tipo de movimentao ser uma

    Enum.

    package br.com.caelum.estoque;

    public enum TipoMovimentacao {

    ENTRADA SAIDA

    }

    Porm no basta apenas termos esta nova entidade, precisamos alterar a lgica de alterao de produtos.

    Nesta nova lgica ao alterar a quantidade de um produto, calcularemos se a movimentao de sada ou

    entrada e a quantidade movimentada. Para isso isolaremos esta lgica em um novo cdigo:

    @Service

    public class GeradorDeM ovimentacao {

    private final ProdutoDA O produtoDA O;

    @Autowired

    public GeradorDeMovimentacao(@Q ualifier("produtoHibernateDA0")ProdutoDA 0 produtoDAO) {

    this.produtoDAO = produtoDAO;

    public Movimentacao geraMovim entacao(Produto produto) {

    Movimentacao mov = new Movimentacao();

    mov.setData(Calendar.getInstance());

    mov.setProduto(produto);

    Integer quantidadeAtual = produtoDAO.estoqueAtual(produto);

    if(produto.getQuantidade()>quantidadeAtual){

    mov.setTipo(TipoMovimentacao.ENTRADA);

    }else{

    mov.setTipo(TipoMovimentacao.SAIDA);

    }

    mov. setQuantidade(Math. abs (produto .getQuantidadeO-quantidadeA

    tual));

    return m ov;

    }

    }

    Basicamente o que o mtodo

    geraMovimentacao

    faz receber um produto com a quantidade nova de itens

    e comparar com a atual, descobrindo se a movimentao de entrada ou sada.

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - Entitidade - Pgina 45

  • 7/18/2019 FJ27 Caelum Spring

    52/98

    Caelum http://www.caelum.com.br

    Spring Framework 3

    Tambm precisamos mexer no mtodo

    alterar da

    ProdutosControl ler

    para usar o geradorDeMovimenta-

    cao:

    @RequestMapping(value="/alterar" , method=RequestMethod.POST)

    public String alterar(Produto produto) {

    Movimentacao movimentacao = geradorDeMovimentacao.geraMovimentacao(produto);

    movimentacaoDao.salvar(movimentacao);

    produtoDAO.alterar(produto);

    return "redirect:/produtos/listar.html";

    }

    Agora toda as vezes que alterarmos a quantidade de um produto, ser gerada uma movimentao.

    5.18 Exerccios

    1)

    Crie a entidade Movimentacao e a classe

    TipoMovimentacao,

    no esquea das anotaes do Hibernate e de

    registrar a entidade no xml do Spring:

    package br.com.caelum.estoque;

    @Entity

    public class Movimentacao {

    @Id

    @GeneratedValue

    private Long id;

    private Calendar data;

    @Enumerated(EnumType.STRING)

    private TipoMovimentacao tipo;

    private Integer quantidade;

    @ManyToOne

    private Produto produto;

    //getters e setters

    }

    package br.com.caelum.estoque;

    public enum TipoMovimentacao

    ENTRADA, SAIDA

    }

    2)

    Altere a interface

    ProdutoDA0

    adicionando o mtodo

    estoqueAtual:

    public interface ProdutoDA0 {

    void salvar(Produto produuto);

    void alterar(Produto produto);

    List listar();

    Produto buscarPorld(Long id);

    Integer estoqueAtual(Produto produto);

    }

    Ao alterar a interface precisamos implementar este novo mtodo nas classes

    ProdutoHibernateDAO

    e

    ProdutoMemoriaDAO.

    Captulo 5 - Integrando Spring, Hibernate e tecnologias de Persistncia - Exerccios - Pgina 46

  • 7/18/2019 FJ27 Caelum Spring

    53/98

    Caelumhttp://www.caelum.com.br

    Spring Framework 3

    public class ProdutoHibernateDAO

    implements ProdutoDA0 {

    / /outros m etodos ja existentes

    public

    Integer estoqueA tual(Produto produto) {

    Query query = factory.getCurrentSession()

    .createQuery("select quantidade from Produto w here id = :pid");

    query.setParameter("pid", produto.getId());

    return (Integer) query.uniqueResu lt() ;

    public

    class ProdutoMem oriaDA0 implements ProdutoDA0 {

    / /outros metodos ja

    existentes

    public

    Integer estoqueAtual(