Simplificando o desenvolvimento
Java/Java EE - 2006




Maurício Linhares http://techbot.me/
No início era apenas o profeta...


                     Eu trago a
                    linguagem
                       que vai
                   funcionar em
                      todas as
                   plataformas!
                    Liberdade!
Mas a liberdade virou Libertinagem
          Só quem tá certo      Eu faço
            aqui sou eu!        melhor!




Não! Eu
 faço
melhor!
Acabou a farra!
      Agora quem não
         seguir as
     especificações vai
     para os campos de
       concentração!




JCP Hitler
EJB, BMP, JMS, CMP,
 JAAS, JSP, JSTL, JCA,
JTA, JDBC, AWT, JNDI!

Aprendam ou morram!
Porque é tão
     complicado
    desenvolver
aplicações Java EE?
Já tá na
  hora de
simplificar
   isso.
Vamos criar
     um
Framework
    para
  resolver
    esse
 problema!
Vamos criar um framework!


Mas o que é um   framework?
O que é?

¡  Umesqueleto semi-pronto para ser
  estendido;

¡  Contém   implementações genéricas;

¡  Deve
       tornar o difícil fácil e o
  impossível possível;
E então surge o grande
Salvador!




    framework
E qual é a missão dele?

¡  Desenvolver  aplicações Java EE tem
    que ser mais fácil;
¡  Programar para interfaces é melhor
    do que programar para classes
    concretas;
¡  Desenvolvimento orientado a
    objetos é mais importante do que a
    tecnologia utilizada;
O que ele oferece pra isso?

¡  Um  container de Inversão de
    Controle;
¡  Abstração para o controle de
    transações;
¡  Abstração para bancos de dados;

¡  Programação Orientada a Aspectos;

¡  Integração com vários outros
    projetos;
E quem
disse que eu
 sei o que é
 essa tal de
Inversão de
  Controle?
A Inversão de Controle
redefine...


...dois princípios da
Orientação a Objetos
Objetos não devem mostrar
suas intimidades...
Objetos devem ser auto contidos...
E o que é
   que a
Inversão de
  controle
    diz?
Objetos devem informar os
contratos que eles precisam
implementar


Trabalhando com contratos (ou
interfaces) as intimidades deles não
vão interessar a ninguém
Os objetos devem dizer de
quais objetos eles dependem


Pra que alguém possa fornecer essas
dependências
Inversão de Controle também
é...


... uma inversão de
responsabilidades
Inversão de qual
responsabilidade?
Os dois princípios foram
realmente redefinidos?


O que?
Quando?
Porque?
Onde está Wally?
Existem dois tipos de inversão

¡  Injeção   de dependências;




¡  Busca   por dependências;
Busca por dependências

¡  Quem   precisa, tem que correr
    atrás;
¡  As dependências ficam em um
    contexto geral do sistema, ou não;
¡  Costumam ser disponibilizadas em
    eventos específicos;
Injeção de dependências

¡  Quem  precisa, diz que precisa e
    recebe na mão;
¡  As dependências ficam onde elas
    quiserem ficar;
¡  Podem ser disponibilizadas a
    qualquer momento, depende de
    quem precisa;
Voltando ao nosso assunto...


... Vejamos como é
possível acessar o Spring
Acessando o Spring

¡  Configurado   com (mais um) arquivo
    XML;
¡  Os objetos ficam no
    ApplicationContext;
¡  Os objetos não podem depender de
    objetos que não estejam no
    ApplicationContext;
Um ApplicationContext pode ser criado
pelas seguintes classes:

¡  FileSystemXmlApplicationContext



¡  ClassPathXmlApplicationContext



¡  Emuma aplicação web o contexto
  normalmente é carregado por um
  ServletContextListener específico do
  Spring
Meu primeiro SpringBean
<bean
  id="autenticador"

  class="org.maujr.newsletter.Autenti
  cador">
  <property name="usuario">
     <value>mauricio.linhares</value>
  </property>
</bean>
Como ficam os objetos
¡  Todos são singletons por default;
¡  Cada um deve ter o seu próprio
     id ;
¡  Podem ser referenciados em um
    arquivo e utilizados em outro;
¡  As dependências só são inseridas
    uma única vez;
¡  Não é possível acessar objetos que
    não tem um contrutor público;
Mas eu
não quero
   um
Singleton!
Calma, calma!
<bean
  id="autenticador"

  class="org.maujr.newsletter.Autenti
  cador
  singleton= false >
  <property name="usuario">
     <value>mauricio.linhares</value>
  </property>
</bean>
O ApplicationContext transforma
automaticamente de String para:

¡  Tipos numéricos;
¡  Class;

¡  URL;

¡  File;

¡  Array de Strings (separando por
    vírgulas);
E os outros tipos?
São transformados de String


para os seus objetos
usando PropertyEditors
customizados
Como eu crio um PropertyEditor?

¡  Extendendo   a classe
    PropertyEditorSupport;
¡  Implementando os métodos
    setAsText() e getAsText();
¡  E basta registrar ele no
    ApplicationContext;
¡  99% das vezes isso não é
    necessário;
<property/>

Define uma propriedade do bean que
vai ser inserida pelo Spring, pode
conter diversas outras tags dentro
dela
<constructor-arg/>


Funciona da mesma maneira que a
tag <property/>, mas passa as
dependências como parâmetros do
construtor
<ref/>


Referencia um outro bean que esteja
configurado. Pode ser um bean no
mesmo arquivo ou em arquivos
diferentes
Outras tags

¡  <props/>

¡  <list/>

¡  <map/>

¡  <set/>

¡  <value/>
E se eu
 não tiver
   como
  chamar
    um
construtor
     ?
FactoryBeans estão na mão!
Implementando a interface
FactoryBean

¡  O método getObject() retorna o
    objeto que essa fábrica deve
    produzir;
¡  O método isSingleton() avisa se o
    objeto produzido é um singleton ou
    não;
¡  O método getObjectType() deve
    retonar o tipo (Class) do objeto que
    esta fábrica produz;
Como implementar o acesso ao
banco de dados no nosso
sistema?


Por que não deixar as classes
acessarem a classe utilitária
diretamente?
Nosso primeiro FactoryBean


O gerenciador das conexões com o
banco de dados
Qual a responsabilidade dele?


Abrir conexões com o banco de dados
para que os repositórios possam
trabalhar livremente
Como funciona o nosso banco?




Conexões
ObjectContainers


                          Banco de dados
                          ObjectServer
Em código...

ObjectServer bancoDeDados =
 Db4o.openServer(nomeDoArquivo,
 porta);
O que é um Repositório?
Um adaptador entre mecanismos
distintos
Como é o nosso repositório?
public interface Repositorio {

    public void adicionar(Persistivel objeto);

    public void atualizar(Persistivel objeto);

    public void remover (Persistivel objeto);

    public Persistivel pegarPeloId(Long id);

    public List pegarTodos(Class clazz);

}
A nossa implementação dele...


...é a classe RepositorioDoDb4o
Ei!
Essa classe
é abstrata!
O método getContainer() é
abstrato


Então nós temos que
encontrar uma maneira de
oferecer os ObjectContaners
da nossa fábrica
Mas ainda existe outro
problema


O Repositório é um singleton, mas
tem que receber novos
ObjectContainers a cada chamada do
método getContainer()
Como resolver isso?

¡  Criar uma classe que estenda a
    RepositorioDoDb4o;
¡  Implementar a interface
    ApplicationContextAware;
¡  Pegar o ApplicationContext e pegar
    os ObjectContainers diretamente;
Em código....
public class RepositorioSpring extends RepositorioDoDb4o
  implements ApplicationContextAware {

    private ApplicationContext context;

    public ObjectContainer getContainer() {
         return context.getBean( objectContainerFactory );
    }

    public void setApplicationContext(ApplicationContext
    context) {
         this.context = context;
    }

}
Isso tá
   muito
complicado!
Injeção de métodos


Um objeto Singleton pode depender
de objetos não-Singleton sem
problemas
Como isso é feito?


O Spring responde pela dependência
em vez do objeto dependente
Em código
<bean id="repositorio"
  class="org.maujr.persistencia.db4o.
  RepositorioDoDb4o">
  <lookup-method
   bean="objectContainerFactory"
   name="getContainer"/>
</bean>

<bean
id="objectContainerFactory"
class="org.maujr.persistencia.db4o.Ob
  jectContainerFactory"/>
O que vai acontecer?


Sempre que o método getContainer()
for chamado no Repositório, o
FactoryBean que cria os
ObjectContainers vai ser chamado
Complicando um pouco mais...


Ninguém está fechando as transações
nem as conexões com o banco.

Onde isto está acontecendo?
No FiltroDoDb4o


Ele faz o commit ou rollback das
transações e no fim fecha a conexão
com o banco de dados;
Em código...
try {
        chain.doFilter(request, response);
        ServerUtil.commitTransaction();

} catch (Exception e) {
      e.printStackTrace();
      ServerUtil.rollbackTransaction();

} finally {
      ServerUtil.closeContainer();
}
E qual é a
vantagem
  disso?
Todo o código está livre da
interação com o banco


O Spring provê mecanismos mais
simples de se utilizar para os
frameworks mais conhecidos, como o
Hibernate
Spring MVC


Simplificando o Desenvolvimento web
com o Spring
Peraí!

É necessário adicionar o Servlet que
vai responder as requisições do
Spring no web.xml com um
mapeamento

Sem o Servlet do Spring ele não pode
responder a requisições feitas ao
servidor
Características
¡    Várias classes de suporte para formulários
      e requisições normais;
¡    Transformação automática de valores do
      request para objetos;
¡    Suporte transparente a vários
      mecanismos de visualização;
¡    Totalmente configurado dentro do próprio
      Spring
¡    Os controladores não são thread-safe;
Mapeadores de URL

Existem várias estratégias
disponíveis, mas os mais utilizados
são BeanNameUrlHandlerMapping e o
SimpleUrlHandlerMapping
BeanNameUrlHandlerMapping

Direciona as requisições para as
classes através dos seus
identificadores.

Uma requisição para /
contados.html seria enviada para o
bean com o ID /contados.html
SimpleUrlHandlerMapping

Mais complexo, direciona as
requisições através de um mapa de
chaves e valores. É possível usar
 curingas como * nas URLs.
Em código...
<bean id="urlMapper"
  class="org.springframework.web.servlet.handler
  .SimpleUrlHandlerMapping">
<property name="mappings">
  <props>
      <prop key="/noticia.html">
             inserirNoticiaAction
      </prop>
      <prop key="/noticias.html">
             listarNoticiasAction
      </prop>
      <prop key="/principal.html">
             principalAction
      </prop>
  </props>
</property>
</bean>
ViewResolvers

¡  São as classes responsáveis pela
    descoberta das views;
¡  Transformam nomes lógicos em
    uma requisição para a view
    apropriada;
Em código....
<bean id="viewResolver"
  class="org.springframework.web.serv
  let.view.ResourceBundleViewResolver
  ">
  <property name="basenames">
     <value>views</value>
  </property>
  <property name="defaultParentView">
     <value>mostrar-principal</value>
  </property>
</bean>
Configurando...
mostrar-principal.class=
  org.springframework.web.servlet.view.velocity
  .VelocityView
mostrar-principal.url= org/maujr/velocity/
  principal.html
mostrar-principal.exposeSpringMacroHelpers=
  true

noticia.url=org/maujr/velocity/noticia.html
noticia.exposeSpringMacroHelpers=true

noticias.url=org/maujr/velocity/noticias.htm
A interface Controller

¡  É a interface base para a parte web
    do Spring;
¡  Define um único método,
     handleRequest() que deve
    retornar um objeto ModelAndView;
¡  Esse é o método chamado quando
    uma dessas classes recebe uma
    requisição HTTP;
Os objetos ModelAndView

¡  Servem   como abstração para
    colocação de objetos que devem
    aparecer na visualização;
¡  Também recebe o nome lógico pelo
    qual a view responsável vai ser
    encontrada;
¡  Não é necessário indicar qual o tipo
    da view que vai gerar a resposta;
Controlador AbstractController
¡  Classe simples para a resposta a
    requisições diretas;
¡  Não é indicada para o uso de
    formulários;
¡  Pode responder a qualquer método
    HTTP;
¡  Não tem suporte a validação;
¡  O método que deve ser sobrescrito
    é o handleRequestInternal()
Criando o ListarAction

¡  Umobjeto que lista todos os
  objetos de uma certa classe;

¡  Faz
      uma busca utilizando o
  repositório;
Propriedades do nosso objeto

 private Class classe;

 private String view;

 private Repositorio repositorio;
Em código...
protected ModelAndView handleRequestInternal
  (HttpServletRequest request,
             HttpServletResponse response) throws
  Exception {

  ModelAndView mv = new ModelAndView
  ( this.getView() );

  mv.getModel().put("objetos", this.getRepositorio
  ().pegarTodos( this.getClasse()) );

  return mv;
  }
O Controlador SimpleFormController

¡  É utilizado para lidar com
    formulários;
¡  Faz a conversão automática de tipos
    primitivos e também pode registrar
    seus próprios PropertyEditors;
¡  Tem suporte a validação;
¡  Os objetos podem ficar na sessão
    ou podem ser recriados a cada
    requisição
Configurando
<bean id="inserirNoticiaAction"
  class="org.maujr.action.FormAction">
  <property name="commandClass">
      <value>org.maujr.noticia.Noticia</value>
  </property>
  <property name="formView">
      <value>noticia</value>
  </property>
  <property name="successView">
      <value>noticias-redirect</value>
  </property>
  <property name="validator">
      <ref bean="noticiasValidator"/>
  </property>
  <property name="repositorio">
      <ref bean="repositorio"/>
  </property>
</bean>
É o mesmo objeto para o GET e o
POST

¡  NoGET ele carrega o objeto e
  coloca ele para ser visualizado no
  método formBackingObject();

¡  No
     POST ele faz a validação do
  formulário e se não tiver nenhum
  erro chama o método onSubmit();
Criando o FormAction

¡  É responsável por inserir e editar os
    objetos no banco de dados;
¡  É capaz de tranformar todas as
    propriedades simples;
¡  Pode ser extendido para lidar com
    propriedades complexas;
Quando ele recebe um GET
String id = request.getParameter("chave");

if ( id != null ) {
   Persistivel objeto
   =repositorio.pegarPeloId( new Long(id) );
   return objeto;
}

return super.formBackingObject(request);
Quando ele recebe um POST

this.getRepositorio().adicionar
  ( (Persistivel) command);

return new ModelAndView
  ( this.getSuccessView() );
Sequência de execução do Spring
MVC
Não estou
vendo a
validação!
A validação é feita pela
interface Validator


Basta implementar os métodos
supports() e validate(). Quando
ocorrer um erro, chama-se o método
 reject() no objeto Errors, o Spring
retorna a requisição e mostra o erro
automaticamente.
Em código...
public void validate(Object obj, Errors
  errors) {

Pessoa pessoa = (Pessoa) obj;
  if (pessoa.getNome() == null) {

    errors.rejectValue( nome , obrigatorio ,
     Este campo é obrigatório );
    }
}
Revisando...
O que é...


Inversão de controle?
Quais são os...


Tipos de inversão de
controle?
É possível...


Utilizar objetos que não
tenham construtores
públicos?
O que é...


Um FactoryBean?
Todos os objetos...


Tem que ser singletons?
E então?


           Acabou?
Agora eu
   vou
dominar a
Fenda do
 Biquini!
Não tão rápido!
Ainda falta o Velocity!
O que é o Velocity?


É uma ferramenta de geração texto
dinamicamente, para aplicações
desktop ou web
Como ele funciona?
¡  Você  escreve um arquivo de texto
    qualquer com as diretivas da
    Velocity Template Language (VTL);
¡  Manda o Velocity carregar o
    arquivo;
¡  Cria um conjunto de objetos que vai
    ser utilizado para gerar o resultado;
¡  E recebe um String com o que for
    criado;
VelocityEngine

¡  É a classe que é utilizada para se
    acessar o Velocity;
¡  Faz o carregamento dos Templates;

¡  Uma mesma VelocityEngine pode
    ser reutilizada por toda a aplicação;
Configurando uma VelocityEngine
engine = new VelocityEngine();

Properties props = new Properties();

props.put("resource.loader", "class");

props.put("class.resource.loader.class",
  ClasspathResourceLoader.class.getName());

props.put("class.resource.loader.cache",
  "false");

engine.init(props);
Criando e executando um template
Template template =
  engine.getTemplate("org/maujr/
  velocity/noticias.html");
Context context = new VelocityContext
  ();
List<Noticia> noticias = new
  ArrayList<Noticia>();
//criando as notícias
context.put("objetos", noticias);

Writer writer = new StringWriter();
template.merge(context, writer);
System.out.println(writer.toString());
O que é a VTL?


É uma linguagem simples para o
tratamento dos templates
Utilizando uma variável do Context

¡  $nomeDaVariável   – Declaração
 simples

¡  ${nomeDaVariavel}   – Declaração
 completa

¡  $!{nomeDaVariavel}   – Declaração
 silenciosa
Chamando métodos


Métodos que não recebem
parâmetros podem ser chamados
normalmente, como em:

${pessoa.calcularPeso()}
Acessando propriedades
JavaBeans

Propriedades JavaBeans podem ser
acessadas da mesma maneira que
em Expression Language:

${noticia.titulo}
${aluno.curso.nome}
Tem alguma diferença?

<a href= /verArtigo/$command.id.do >
 Ver artigo
</a>

<a href= /verArtigo/${command.id}.do >
 Ver artigo
</a>
Como criar uma variável no
template?


Usando #set:

#set( $nome = Maurício )
Execução Condicional - #if
¡  Operador  para tratar condições
¡  Recebe um boolean
¡  Se o valor retornar null ele
    interpreta como false
¡  Pode conter uma condição #else
¡  Pode conter várias condições #elseif
    para funcionar como um switch
¡  Pode conter os operadores ==, >=,
    <= e !=
Em código....

#if (${command.id})
  <input type="hidden"
     name="chave"    value="$!
  {command.id}"/>
#end
Em código com #else e #elseif

#if (${command.id})
  <input type="hidden"
     name="chave"    value="$!
  {command.id}"/>
#elseif (${command.id} == 10)
  O valor do id é 10
#else
  Caiu no Else
#end
Passeando pelas coleções com
#foreach

¡  Faz a iteração dentro de todas as
    coleções do Java
¡  Não tem controle nativo do
    tamanho do loop
¡  O contador pode ser acessado pela
    variável ${velocityCounter}
Em código...
#foreach($noticia in ${objetos})
  <tr>
     <td>${noticia.titulo}</td>
     <td>${noticia.texto}</td>
     <td>
          <a href="noticia.html?chave=$
  {noticia.id}">
               Editar
          </a>
     </td>
</tr>
#end
E esse
#springBind é
   o que?
É um #macro!


Um macro é uma função que pode
ser reutilizada em vários templates
diferentes
Como se define isso?

#macro (nomeDoMacro $variavel
 $outraVariavel $maisOutra)

 escreve qualquer coisa

#end
Onde colocar isso?

¡  Macros  devem ser colocados em
    arquivos separados
¡  Eles são carregados pelo próprio
    Velocity quando uma VelocityEngine
    é criada, através da propriedade
     velocimacro.library
Em código...

velocimacro.library=spring.vm

Ou se forem vários:

velocimacro.library=
  spring.vm,struts.vm,webwork.vm
Incluindo conteúdo estático
com #include


Inclui um arquivo de texto qualquer,
mas não faz avaliações de VTL ou
variáveis
Em código

#include( noticias.html )

#include( noticias.html ,
   rodape.html , topo.html )
Incluindo templates dinâmicos
com #parse


Funciona do mesmo modo que o
#include, mas faz avaliação de
conteúdo dinâmico em VTL
E agora?


Acabou?
Mais alguma coisa?
Tá na hora de ir pegar o menino na
escola?
Agora eu vou
 colocar em
  prática o
 meu plano
  maligno!
A aplicação de exemplo precisa de
novas funcionalidades

¡  Cadastrar,   editar e listar usuários

¡  Montar
         as mensagens de e-mail que
  vão ser enviadas para cada
  endereço
Trabalhem!
Referências

¡  Harrop, Rob; Machacek, Jan. Pro
    Spring. Apress, 2005.
¡  Harrop, Rob. Pro Jakarta Velocity.
    Apress, 2004.
¡  Evans, Eric. Domain Driven
    Design:Tackling Complexity in
    the Heart of Software. Addisson-
    Wesley, 2004
Referências

¡  Johnson, Rod; Hoeller, Juergen.
    Expert One-On-One J2EE
    Development Without EJB. Wrox
    Press, 2004
¡  Johnson, Rod. Expert One-On-One
    J2EE Development. Wrox Press,
    2002
Trilha Sonora


                       Arch Enemy – Doomsday Machine




Black Label Society - Mafia
Trilha Sonora


                        Therion – Lemuria & Sirus B




Nickelback – All The Right Reasons
Conhecendo o Spring

Conhecendo o Spring

  • 1.
    Simplificando o desenvolvimento Java/JavaEE - 2006 Maurício Linhares http://techbot.me/
  • 2.
    No início eraapenas o profeta... Eu trago a linguagem que vai funcionar em todas as plataformas! Liberdade!
  • 3.
    Mas a liberdadevirou Libertinagem Só quem tá certo Eu faço aqui sou eu! melhor! Não! Eu faço melhor!
  • 4.
    Acabou a farra! Agora quem não seguir as especificações vai para os campos de concentração! JCP Hitler
  • 5.
    EJB, BMP, JMS,CMP, JAAS, JSP, JSTL, JCA, JTA, JDBC, AWT, JNDI! Aprendam ou morram!
  • 6.
    Porque é tão complicado desenvolver aplicações Java EE?
  • 7.
    Já tá na hora de simplificar isso.
  • 8.
    Vamos criar um Framework para resolver esse problema!
  • 9.
    Vamos criar umframework! Mas o que é um framework?
  • 10.
    O que é? ¡ Umesqueleto semi-pronto para ser estendido; ¡  Contém implementações genéricas; ¡  Deve tornar o difícil fácil e o impossível possível;
  • 11.
    E então surgeo grande Salvador! framework
  • 12.
    E qual éa missão dele? ¡  Desenvolver aplicações Java EE tem que ser mais fácil; ¡  Programar para interfaces é melhor do que programar para classes concretas; ¡  Desenvolvimento orientado a objetos é mais importante do que a tecnologia utilizada;
  • 13.
    O que eleoferece pra isso? ¡  Um container de Inversão de Controle; ¡  Abstração para o controle de transações; ¡  Abstração para bancos de dados; ¡  Programação Orientada a Aspectos; ¡  Integração com vários outros projetos;
  • 14.
    E quem disse queeu sei o que é essa tal de Inversão de Controle?
  • 15.
    A Inversão deControle redefine... ...dois princípios da Orientação a Objetos
  • 16.
    Objetos não devemmostrar suas intimidades...
  • 17.
    Objetos devem serauto contidos...
  • 18.
    E o queé que a Inversão de controle diz?
  • 19.
    Objetos devem informaros contratos que eles precisam implementar Trabalhando com contratos (ou interfaces) as intimidades deles não vão interessar a ninguém
  • 20.
    Os objetos devemdizer de quais objetos eles dependem Pra que alguém possa fornecer essas dependências
  • 21.
    Inversão de Controletambém é... ... uma inversão de responsabilidades
  • 22.
  • 23.
    Os dois princípiosforam realmente redefinidos? O que? Quando? Porque? Onde está Wally?
  • 24.
    Existem dois tiposde inversão ¡  Injeção de dependências; ¡  Busca por dependências;
  • 25.
    Busca por dependências ¡ Quem precisa, tem que correr atrás; ¡  As dependências ficam em um contexto geral do sistema, ou não; ¡  Costumam ser disponibilizadas em eventos específicos;
  • 26.
    Injeção de dependências ¡ Quem precisa, diz que precisa e recebe na mão; ¡  As dependências ficam onde elas quiserem ficar; ¡  Podem ser disponibilizadas a qualquer momento, depende de quem precisa;
  • 27.
    Voltando ao nossoassunto... ... Vejamos como é possível acessar o Spring
  • 28.
    Acessando o Spring ¡ Configurado com (mais um) arquivo XML; ¡  Os objetos ficam no ApplicationContext; ¡  Os objetos não podem depender de objetos que não estejam no ApplicationContext;
  • 29.
    Um ApplicationContext podeser criado pelas seguintes classes: ¡  FileSystemXmlApplicationContext ¡  ClassPathXmlApplicationContext ¡  Emuma aplicação web o contexto normalmente é carregado por um ServletContextListener específico do Spring
  • 30.
    Meu primeiro SpringBean <bean id="autenticador" class="org.maujr.newsletter.Autenti cador"> <property name="usuario"> <value>mauricio.linhares</value> </property> </bean>
  • 31.
    Como ficam osobjetos ¡  Todos são singletons por default; ¡  Cada um deve ter o seu próprio id ; ¡  Podem ser referenciados em um arquivo e utilizados em outro; ¡  As dependências só são inseridas uma única vez; ¡  Não é possível acessar objetos que não tem um contrutor público;
  • 32.
    Mas eu não quero um Singleton!
  • 33.
    Calma, calma! <bean id="autenticador" class="org.maujr.newsletter.Autenti cador singleton= false > <property name="usuario"> <value>mauricio.linhares</value> </property> </bean>
  • 34.
    O ApplicationContext transforma automaticamentede String para: ¡  Tipos numéricos; ¡  Class; ¡  URL; ¡  File; ¡  Array de Strings (separando por vírgulas);
  • 35.
  • 36.
    São transformados deString para os seus objetos usando PropertyEditors customizados
  • 37.
    Como eu crioum PropertyEditor? ¡  Extendendo a classe PropertyEditorSupport; ¡  Implementando os métodos setAsText() e getAsText(); ¡  E basta registrar ele no ApplicationContext; ¡  99% das vezes isso não é necessário;
  • 38.
    <property/> Define uma propriedadedo bean que vai ser inserida pelo Spring, pode conter diversas outras tags dentro dela
  • 39.
    <constructor-arg/> Funciona da mesmamaneira que a tag <property/>, mas passa as dependências como parâmetros do construtor
  • 40.
    <ref/> Referencia um outrobean que esteja configurado. Pode ser um bean no mesmo arquivo ou em arquivos diferentes
  • 41.
    Outras tags ¡  <props/> ¡ <list/> ¡  <map/> ¡  <set/> ¡  <value/>
  • 42.
    E se eu não tiver como chamar um construtor ?
  • 43.
  • 44.
    Implementando a interface FactoryBean ¡ O método getObject() retorna o objeto que essa fábrica deve produzir; ¡  O método isSingleton() avisa se o objeto produzido é um singleton ou não; ¡  O método getObjectType() deve retonar o tipo (Class) do objeto que esta fábrica produz;
  • 45.
    Como implementar oacesso ao banco de dados no nosso sistema? Por que não deixar as classes acessarem a classe utilitária diretamente?
  • 46.
    Nosso primeiro FactoryBean Ogerenciador das conexões com o banco de dados
  • 47.
    Qual a responsabilidadedele? Abrir conexões com o banco de dados para que os repositórios possam trabalhar livremente
  • 48.
    Como funciona onosso banco? Conexões ObjectContainers Banco de dados ObjectServer
  • 49.
    Em código... ObjectServer bancoDeDados= Db4o.openServer(nomeDoArquivo, porta);
  • 50.
    O que éum Repositório?
  • 51.
    Um adaptador entremecanismos distintos
  • 52.
    Como é onosso repositório? public interface Repositorio { public void adicionar(Persistivel objeto); public void atualizar(Persistivel objeto); public void remover (Persistivel objeto); public Persistivel pegarPeloId(Long id); public List pegarTodos(Class clazz); }
  • 53.
    A nossa implementaçãodele... ...é a classe RepositorioDoDb4o
  • 54.
  • 55.
    O método getContainer()é abstrato Então nós temos que encontrar uma maneira de oferecer os ObjectContaners da nossa fábrica
  • 56.
    Mas ainda existeoutro problema O Repositório é um singleton, mas tem que receber novos ObjectContainers a cada chamada do método getContainer()
  • 57.
    Como resolver isso? ¡ Criar uma classe que estenda a RepositorioDoDb4o; ¡  Implementar a interface ApplicationContextAware; ¡  Pegar o ApplicationContext e pegar os ObjectContainers diretamente;
  • 58.
    Em código.... public classRepositorioSpring extends RepositorioDoDb4o implements ApplicationContextAware { private ApplicationContext context; public ObjectContainer getContainer() { return context.getBean( objectContainerFactory ); } public void setApplicationContext(ApplicationContext context) { this.context = context; } }
  • 59.
    Isso tá muito complicado!
  • 60.
    Injeção de métodos Umobjeto Singleton pode depender de objetos não-Singleton sem problemas
  • 61.
    Como isso éfeito? O Spring responde pela dependência em vez do objeto dependente
  • 62.
    Em código <bean id="repositorio" class="org.maujr.persistencia.db4o. RepositorioDoDb4o"> <lookup-method bean="objectContainerFactory" name="getContainer"/> </bean> <bean id="objectContainerFactory" class="org.maujr.persistencia.db4o.Ob jectContainerFactory"/>
  • 63.
    O que vaiacontecer? Sempre que o método getContainer() for chamado no Repositório, o FactoryBean que cria os ObjectContainers vai ser chamado
  • 64.
    Complicando um poucomais... Ninguém está fechando as transações nem as conexões com o banco. Onde isto está acontecendo?
  • 65.
    No FiltroDoDb4o Ele fazo commit ou rollback das transações e no fim fecha a conexão com o banco de dados;
  • 66.
    Em código... try { chain.doFilter(request, response); ServerUtil.commitTransaction(); } catch (Exception e) { e.printStackTrace(); ServerUtil.rollbackTransaction(); } finally { ServerUtil.closeContainer(); }
  • 67.
    E qual éa vantagem disso?
  • 68.
    Todo o códigoestá livre da interação com o banco O Spring provê mecanismos mais simples de se utilizar para os frameworks mais conhecidos, como o Hibernate
  • 69.
    Spring MVC Simplificando oDesenvolvimento web com o Spring
  • 70.
    Peraí! É necessário adicionaro Servlet que vai responder as requisições do Spring no web.xml com um mapeamento Sem o Servlet do Spring ele não pode responder a requisições feitas ao servidor
  • 71.
    Características ¡  Várias classes de suporte para formulários e requisições normais; ¡  Transformação automática de valores do request para objetos; ¡  Suporte transparente a vários mecanismos de visualização; ¡  Totalmente configurado dentro do próprio Spring ¡  Os controladores não são thread-safe;
  • 72.
    Mapeadores de URL Existemvárias estratégias disponíveis, mas os mais utilizados são BeanNameUrlHandlerMapping e o SimpleUrlHandlerMapping
  • 73.
    BeanNameUrlHandlerMapping Direciona as requisiçõespara as classes através dos seus identificadores. Uma requisição para / contados.html seria enviada para o bean com o ID /contados.html
  • 74.
    SimpleUrlHandlerMapping Mais complexo, direcionaas requisições através de um mapa de chaves e valores. É possível usar curingas como * nas URLs.
  • 75.
    Em código... <bean id="urlMapper" class="org.springframework.web.servlet.handler .SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/noticia.html"> inserirNoticiaAction </prop> <prop key="/noticias.html"> listarNoticiasAction </prop> <prop key="/principal.html"> principalAction </prop> </props> </property> </bean>
  • 76.
    ViewResolvers ¡  São asclasses responsáveis pela descoberta das views; ¡  Transformam nomes lógicos em uma requisição para a view apropriada;
  • 77.
    Em código.... <bean id="viewResolver" class="org.springframework.web.serv let.view.ResourceBundleViewResolver "> <property name="basenames"> <value>views</value> </property> <property name="defaultParentView"> <value>mostrar-principal</value> </property> </bean>
  • 78.
    Configurando... mostrar-principal.class= org.springframework.web.servlet.view.velocity .VelocityView mostrar-principal.url= org/maujr/velocity/ principal.html mostrar-principal.exposeSpringMacroHelpers= true noticia.url=org/maujr/velocity/noticia.html noticia.exposeSpringMacroHelpers=true noticias.url=org/maujr/velocity/noticias.htm
  • 79.
    A interface Controller ¡ É a interface base para a parte web do Spring; ¡  Define um único método, handleRequest() que deve retornar um objeto ModelAndView; ¡  Esse é o método chamado quando uma dessas classes recebe uma requisição HTTP;
  • 80.
    Os objetos ModelAndView ¡ Servem como abstração para colocação de objetos que devem aparecer na visualização; ¡  Também recebe o nome lógico pelo qual a view responsável vai ser encontrada; ¡  Não é necessário indicar qual o tipo da view que vai gerar a resposta;
  • 81.
    Controlador AbstractController ¡  Classesimples para a resposta a requisições diretas; ¡  Não é indicada para o uso de formulários; ¡  Pode responder a qualquer método HTTP; ¡  Não tem suporte a validação; ¡  O método que deve ser sobrescrito é o handleRequestInternal()
  • 82.
    Criando o ListarAction ¡ Umobjeto que lista todos os objetos de uma certa classe; ¡  Faz uma busca utilizando o repositório;
  • 83.
    Propriedades do nossoobjeto private Class classe; private String view; private Repositorio repositorio;
  • 84.
    Em código... protected ModelAndViewhandleRequestInternal (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView ( this.getView() ); mv.getModel().put("objetos", this.getRepositorio ().pegarTodos( this.getClasse()) ); return mv; }
  • 85.
    O Controlador SimpleFormController ¡ É utilizado para lidar com formulários; ¡  Faz a conversão automática de tipos primitivos e também pode registrar seus próprios PropertyEditors; ¡  Tem suporte a validação; ¡  Os objetos podem ficar na sessão ou podem ser recriados a cada requisição
  • 86.
    Configurando <bean id="inserirNoticiaAction" class="org.maujr.action.FormAction"> <property name="commandClass"> <value>org.maujr.noticia.Noticia</value> </property> <property name="formView"> <value>noticia</value> </property> <property name="successView"> <value>noticias-redirect</value> </property> <property name="validator"> <ref bean="noticiasValidator"/> </property> <property name="repositorio"> <ref bean="repositorio"/> </property> </bean>
  • 87.
    É o mesmoobjeto para o GET e o POST ¡  NoGET ele carrega o objeto e coloca ele para ser visualizado no método formBackingObject(); ¡  No POST ele faz a validação do formulário e se não tiver nenhum erro chama o método onSubmit();
  • 88.
    Criando o FormAction ¡ É responsável por inserir e editar os objetos no banco de dados; ¡  É capaz de tranformar todas as propriedades simples; ¡  Pode ser extendido para lidar com propriedades complexas;
  • 89.
    Quando ele recebeum GET String id = request.getParameter("chave"); if ( id != null ) { Persistivel objeto =repositorio.pegarPeloId( new Long(id) ); return objeto; } return super.formBackingObject(request);
  • 90.
    Quando ele recebeum POST this.getRepositorio().adicionar ( (Persistivel) command); return new ModelAndView ( this.getSuccessView() );
  • 91.
  • 92.
  • 93.
    A validação éfeita pela interface Validator Basta implementar os métodos supports() e validate(). Quando ocorrer um erro, chama-se o método reject() no objeto Errors, o Spring retorna a requisição e mostra o erro automaticamente.
  • 94.
    Em código... public voidvalidate(Object obj, Errors errors) { Pessoa pessoa = (Pessoa) obj; if (pessoa.getNome() == null) { errors.rejectValue( nome , obrigatorio , Este campo é obrigatório ); } }
  • 95.
  • 96.
  • 97.
    Quais são os... Tiposde inversão de controle?
  • 98.
    É possível... Utilizar objetosque não tenham construtores públicos?
  • 99.
    O que é... UmFactoryBean?
  • 100.
    Todos os objetos... Temque ser singletons?
  • 101.
    E então? Acabou?
  • 102.
    Agora eu vou dominar a Fenda do Biquini!
  • 103.
    Não tão rápido! Aindafalta o Velocity!
  • 104.
    O que éo Velocity? É uma ferramenta de geração texto dinamicamente, para aplicações desktop ou web
  • 105.
    Como ele funciona? ¡ Você escreve um arquivo de texto qualquer com as diretivas da Velocity Template Language (VTL); ¡  Manda o Velocity carregar o arquivo; ¡  Cria um conjunto de objetos que vai ser utilizado para gerar o resultado; ¡  E recebe um String com o que for criado;
  • 106.
    VelocityEngine ¡  É aclasse que é utilizada para se acessar o Velocity; ¡  Faz o carregamento dos Templates; ¡  Uma mesma VelocityEngine pode ser reutilizada por toda a aplicação;
  • 107.
    Configurando uma VelocityEngine engine= new VelocityEngine(); Properties props = new Properties(); props.put("resource.loader", "class"); props.put("class.resource.loader.class", ClasspathResourceLoader.class.getName()); props.put("class.resource.loader.cache", "false"); engine.init(props);
  • 108.
    Criando e executandoum template Template template = engine.getTemplate("org/maujr/ velocity/noticias.html"); Context context = new VelocityContext (); List<Noticia> noticias = new ArrayList<Noticia>(); //criando as notícias context.put("objetos", noticias); Writer writer = new StringWriter(); template.merge(context, writer); System.out.println(writer.toString());
  • 109.
    O que éa VTL? É uma linguagem simples para o tratamento dos templates
  • 110.
    Utilizando uma variáveldo Context ¡  $nomeDaVariável – Declaração simples ¡  ${nomeDaVariavel} – Declaração completa ¡  $!{nomeDaVariavel} – Declaração silenciosa
  • 111.
    Chamando métodos Métodos quenão recebem parâmetros podem ser chamados normalmente, como em: ${pessoa.calcularPeso()}
  • 112.
    Acessando propriedades JavaBeans Propriedades JavaBeanspodem ser acessadas da mesma maneira que em Expression Language: ${noticia.titulo} ${aluno.curso.nome}
  • 113.
    Tem alguma diferença? <ahref= /verArtigo/$command.id.do > Ver artigo </a> <a href= /verArtigo/${command.id}.do > Ver artigo </a>
  • 114.
    Como criar umavariável no template? Usando #set: #set( $nome = Maurício )
  • 115.
    Execução Condicional -#if ¡  Operador para tratar condições ¡  Recebe um boolean ¡  Se o valor retornar null ele interpreta como false ¡  Pode conter uma condição #else ¡  Pode conter várias condições #elseif para funcionar como um switch ¡  Pode conter os operadores ==, >=, <= e !=
  • 116.
    Em código.... #if (${command.id}) <input type="hidden" name="chave" value="$! {command.id}"/> #end
  • 117.
    Em código com#else e #elseif #if (${command.id}) <input type="hidden" name="chave" value="$! {command.id}"/> #elseif (${command.id} == 10) O valor do id é 10 #else Caiu no Else #end
  • 118.
    Passeando pelas coleçõescom #foreach ¡  Faz a iteração dentro de todas as coleções do Java ¡  Não tem controle nativo do tamanho do loop ¡  O contador pode ser acessado pela variável ${velocityCounter}
  • 119.
    Em código... #foreach($noticia in${objetos}) <tr> <td>${noticia.titulo}</td> <td>${noticia.texto}</td> <td> <a href="noticia.html?chave=$ {noticia.id}"> Editar </a> </td> </tr> #end
  • 120.
  • 121.
    É um #macro! Ummacro é uma função que pode ser reutilizada em vários templates diferentes
  • 122.
    Como se defineisso? #macro (nomeDoMacro $variavel $outraVariavel $maisOutra) escreve qualquer coisa #end
  • 123.
    Onde colocar isso? ¡ Macros devem ser colocados em arquivos separados ¡  Eles são carregados pelo próprio Velocity quando uma VelocityEngine é criada, através da propriedade velocimacro.library
  • 124.
    Em código... velocimacro.library=spring.vm Ou seforem vários: velocimacro.library= spring.vm,struts.vm,webwork.vm
  • 125.
    Incluindo conteúdo estático com#include Inclui um arquivo de texto qualquer, mas não faz avaliações de VTL ou variáveis
  • 126.
    Em código #include( noticias.html) #include( noticias.html , rodape.html , topo.html )
  • 127.
    Incluindo templates dinâmicos com#parse Funciona do mesmo modo que o #include, mas faz avaliação de conteúdo dinâmico em VTL
  • 128.
    E agora? Acabou? Mais algumacoisa? Tá na hora de ir pegar o menino na escola?
  • 129.
    Agora eu vou colocar em prática o meu plano maligno!
  • 130.
    A aplicação deexemplo precisa de novas funcionalidades ¡  Cadastrar, editar e listar usuários ¡  Montar as mensagens de e-mail que vão ser enviadas para cada endereço
  • 131.
  • 132.
    Referências ¡  Harrop, Rob;Machacek, Jan. Pro Spring. Apress, 2005. ¡  Harrop, Rob. Pro Jakarta Velocity. Apress, 2004. ¡  Evans, Eric. Domain Driven Design:Tackling Complexity in the Heart of Software. Addisson- Wesley, 2004
  • 133.
    Referências ¡  Johnson, Rod;Hoeller, Juergen. Expert One-On-One J2EE Development Without EJB. Wrox Press, 2004 ¡  Johnson, Rod. Expert One-On-One J2EE Development. Wrox Press, 2002
  • 134.
    Trilha Sonora Arch Enemy – Doomsday Machine Black Label Society - Mafia
  • 135.
    Trilha Sonora Therion – Lemuria & Sirus B Nickelback – All The Right Reasons