Conhecendo o Spring

925 views
809 views

Published on

Apresentação desenvolvida originalmente para trabalho de disciplina na graduação de Tecnologia em Desenvolvimento para a Internet em 2006.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
925
On SlideShare
0
From Embeds
0
Number of Embeds
75
Actions
Shares
0
Downloads
20
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Conhecendo o Spring

  1. 1. Simplificando o desenvolvimentoJava/Java EE - 2006Maurício Linhares http://techbot.me/
  2. 2. No início era apenas o profeta... Eu trago a linguagem que vai funcionar em todas as plataformas! Liberdade!
  3. 3. Mas a liberdade virou Libertinagem Só quem tá certo Eu faço aqui sou eu! melhor!Não! Eu façomelhor!
  4. 4. Acabou a farra! Agora quem não seguir as especificações vai para os campos de concentração!JCP Hitler
  5. 5. EJB, BMP, JMS, CMP, JAAS, JSP, JSTL, JCA,JTA, JDBC, AWT, JNDI!Aprendam ou morram!
  6. 6. Porque é tão complicado desenvolveraplicações Java EE?
  7. 7. Já tá na hora desimplificar isso.
  8. 8. Vamos criar umFramework para resolver esse problema!
  9. 9. Vamos criar um framework!Mas o que é um framework?
  10. 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. 11. E então surge o grandeSalvador! framework
  12. 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. 13. 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;
  14. 14. E quemdisse que eu sei o que é essa tal deInversão de Controle?
  15. 15. A Inversão de Controleredefine......dois princípios daOrientação a Objetos
  16. 16. Objetos não devem mostrarsuas intimidades...
  17. 17. Objetos devem ser auto contidos...
  18. 18. E o que é que aInversão de controle diz?
  19. 19. Objetos devem informar oscontratos que eles precisamimplementarTrabalhando com contratos (ouinterfaces) as intimidades deles nãovão interessar a ninguém
  20. 20. Os objetos devem dizer dequais objetos eles dependemPra que alguém possa fornecer essasdependências
  21. 21. Inversão de Controle tambémé...... uma inversão deresponsabilidades
  22. 22. Inversão de qualresponsabilidade?
  23. 23. Os dois princípios foramrealmente redefinidos?O que?Quando?Porque?Onde está Wally?
  24. 24. Existem dois tipos de inversão¡  Injeção de dependências;¡  Busca por dependências;
  25. 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. 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. 27. Voltando ao nosso assunto...... Vejamos como épossível acessar o Spring
  28. 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. 29. Um ApplicationContext pode ser criadopelas seguintes classes:¡  FileSystemXmlApplicationContext¡  ClassPathXmlApplicationContext¡  Emuma aplicação web o contexto normalmente é carregado por um ServletContextListener específico do Spring
  30. 30. Meu primeiro SpringBean<bean id="autenticador" class="org.maujr.newsletter.Autenti cador"> <property name="usuario"> <value>mauricio.linhares</value> </property></bean>
  31. 31. 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;
  32. 32. Mas eunão quero umSingleton!
  33. 33. Calma, calma!<bean id="autenticador" class="org.maujr.newsletter.Autenti cador singleton= false > <property name="usuario"> <value>mauricio.linhares</value> </property></bean>
  34. 34. O ApplicationContext transformaautomaticamente de String para:¡  Tipos numéricos;¡  Class;¡  URL;¡  File;¡  Array de Strings (separando por vírgulas);
  35. 35. E os outros tipos?
  36. 36. São transformados de Stringpara os seus objetosusando PropertyEditorscustomizados
  37. 37. 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;
  38. 38. <property/>Define uma propriedade do bean quevai ser inserida pelo Spring, podeconter diversas outras tags dentrodela
  39. 39. <constructor-arg/>Funciona da mesma maneira que atag <property/>, mas passa asdependências como parâmetros doconstrutor
  40. 40. <ref/>Referencia um outro bean que estejaconfigurado. Pode ser um bean nomesmo arquivo ou em arquivosdiferentes
  41. 41. Outras tags¡  <props/>¡  <list/>¡  <map/>¡  <set/>¡  <value/>
  42. 42. E se eu não tiver como chamar umconstrutor ?
  43. 43. FactoryBeans estão na mão!
  44. 44. Implementando a interfaceFactoryBean¡  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. 45. Como implementar o acesso aobanco de dados no nossosistema?Por que não deixar as classesacessarem a classe utilitáriadiretamente?
  46. 46. Nosso primeiro FactoryBeanO gerenciador das conexões com obanco de dados
  47. 47. Qual a responsabilidade dele?Abrir conexões com o banco de dadospara que os repositórios possamtrabalhar livremente
  48. 48. Como funciona o nosso banco?ConexõesObjectContainers Banco de dados ObjectServer
  49. 49. Em código...ObjectServer bancoDeDados = Db4o.openServer(nomeDoArquivo, porta);
  50. 50. O que é um Repositório?
  51. 51. Um adaptador entre mecanismosdistintos
  52. 52. 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);}
  53. 53. A nossa implementação dele......é a classe RepositorioDoDb4o
  54. 54. Ei!Essa classeé abstrata!
  55. 55. O método getContainer() éabstratoEntão nós temos queencontrar uma maneira deoferecer os ObjectContanersda nossa fábrica
  56. 56. Mas ainda existe outroproblemaO Repositório é um singleton, mastem que receber novosObjectContainers a cada chamada dométodo getContainer()
  57. 57. Como resolver isso?¡  Criar uma classe que estenda a RepositorioDoDb4o;¡  Implementar a interface ApplicationContextAware;¡  Pegar o ApplicationContext e pegar os ObjectContainers diretamente;
  58. 58. 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; }}
  59. 59. Isso tá muitocomplicado!
  60. 60. Injeção de métodosUm objeto Singleton pode dependerde objetos não-Singleton semproblemas
  61. 61. Como isso é feito?O Spring responde pela dependênciaem vez do objeto dependente
  62. 62. Em código<bean id="repositorio" class="org.maujr.persistencia.db4o. RepositorioDoDb4o"> <lookup-method bean="objectContainerFactory" name="getContainer"/></bean><beanid="objectContainerFactory"class="org.maujr.persistencia.db4o.Ob jectContainerFactory"/>
  63. 63. O que vai acontecer?Sempre que o método getContainer()for chamado no Repositório, oFactoryBean que cria osObjectContainers vai ser chamado
  64. 64. Complicando um pouco mais...Ninguém está fechando as transaçõesnem as conexões com o banco.Onde isto está acontecendo?
  65. 65. No FiltroDoDb4oEle faz o commit ou rollback dastransações e no fim fecha a conexãocom o banco de dados;
  66. 66. Em código...try { chain.doFilter(request, response); ServerUtil.commitTransaction();} catch (Exception e) { e.printStackTrace(); ServerUtil.rollbackTransaction();} finally { ServerUtil.closeContainer();}
  67. 67. E qual é avantagem disso?
  68. 68. Todo o código está livre dainteração com o bancoO Spring provê mecanismos maissimples de se utilizar para osframeworks mais conhecidos, como oHibernate
  69. 69. Spring MVCSimplificando o Desenvolvimento webcom o Spring
  70. 70. Peraí!É necessário adicionar o Servlet quevai responder as requisições doSpring no web.xml com ummapeamentoSem o Servlet do Spring ele não poderesponder a requisições feitas aoservidor
  71. 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. 72. Mapeadores de URLExistem várias estratégiasdisponíveis, mas os mais utilizadossão BeanNameUrlHandlerMapping e oSimpleUrlHandlerMapping
  73. 73. BeanNameUrlHandlerMappingDireciona as requisições para asclasses através dos seusidentificadores.Uma requisição para /contados.html seria enviada para obean com o ID /contados.html
  74. 74. SimpleUrlHandlerMappingMais complexo, direciona asrequisições através de um mapa dechaves e valores. É possível usar curingas como * nas URLs.
  75. 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. 76. ViewResolvers¡  São as classes responsáveis pela descoberta das views;¡  Transformam nomes lógicos em uma requisição para a view apropriada;
  77. 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. 78. Configurando...mostrar-principal.class= org.springframework.web.servlet.view.velocity .VelocityViewmostrar-principal.url= org/maujr/velocity/ principal.htmlmostrar-principal.exposeSpringMacroHelpers= truenoticia.url=org/maujr/velocity/noticia.htmlnoticia.exposeSpringMacroHelpers=truenoticias.url=org/maujr/velocity/noticias.htm
  79. 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. 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. 81. 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()
  82. 82. Criando o ListarAction¡  Umobjeto que lista todos os objetos de uma certa classe;¡  Faz uma busca utilizando o repositório;
  83. 83. Propriedades do nosso objeto private Class classe; private String view; private Repositorio repositorio;
  84. 84. 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; }
  85. 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. 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. 87. É o mesmo objeto para o GET e oPOST¡  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. 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. 89. Quando ele recebe um GETString id = request.getParameter("chave");if ( id != null ) { Persistivel objeto =repositorio.pegarPeloId( new Long(id) ); return objeto;}return super.formBackingObject(request);
  90. 90. Quando ele recebe um POSTthis.getRepositorio().adicionar ( (Persistivel) command);return new ModelAndView ( this.getSuccessView() );
  91. 91. Sequência de execução do SpringMVC
  92. 92. Não estouvendo avalidação!
  93. 93. A validação é feita pelainterface ValidatorBasta implementar os métodossupports() e validate(). Quandoocorrer um erro, chama-se o método reject() no objeto Errors, o Springretorna a requisição e mostra o erroautomaticamente.
  94. 94. 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 ); }}
  95. 95. Revisando...
  96. 96. O que é...Inversão de controle?
  97. 97. Quais são os...Tipos de inversão decontrole?
  98. 98. É possível...Utilizar objetos que nãotenham construtorespúblicos?
  99. 99. O que é...Um FactoryBean?
  100. 100. Todos os objetos...Tem que ser singletons?
  101. 101. E então? Acabou?
  102. 102. Agora eu voudominar aFenda do Biquini!
  103. 103. Não tão rápido!Ainda falta o Velocity!
  104. 104. O que é o Velocity?É uma ferramenta de geração textodinamicamente, para aplicaçõesdesktop ou web
  105. 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. 106. 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;
  107. 107. Configurando uma VelocityEngineengine = 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. 108. Criando e executando um templateTemplate template = engine.getTemplate("org/maujr/ velocity/noticias.html");Context context = new VelocityContext ();List<Noticia> noticias = new ArrayList<Noticia>();//criando as notíciascontext.put("objetos", noticias);Writer writer = new StringWriter();template.merge(context, writer);System.out.println(writer.toString());
  109. 109. O que é a VTL?É uma linguagem simples para otratamento dos templates
  110. 110. Utilizando uma variável do Context¡  $nomeDaVariável – Declaração simples¡  ${nomeDaVariavel} – Declaração completa¡  $!{nomeDaVariavel} – Declaração silenciosa
  111. 111. Chamando métodosMétodos que não recebemparâmetros podem ser chamadosnormalmente, como em:${pessoa.calcularPeso()}
  112. 112. Acessando propriedadesJavaBeansPropriedades JavaBeans podem seracessadas da mesma maneira queem Expression Language:${noticia.titulo}${aluno.curso.nome}
  113. 113. Tem alguma diferença?<a href= /verArtigo/$command.id.do > Ver artigo</a><a href= /verArtigo/${command.id}.do > Ver artigo</a>
  114. 114. Como criar uma variável notemplate?Usando #set:#set( $nome = Maurício )
  115. 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. 116. Em código....#if (${command.id}) <input type="hidden" name="chave" value="$! {command.id}"/>#end
  117. 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. 118. 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}
  119. 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. 120. E esse#springBind é o que?
  121. 121. É um #macro!Um macro é uma função que podeser reutilizada em vários templatesdiferentes
  122. 122. Como se define isso?#macro (nomeDoMacro $variavel $outraVariavel $maisOutra) escreve qualquer coisa#end
  123. 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. 124. Em código...velocimacro.library=spring.vmOu se forem vários:velocimacro.library= spring.vm,struts.vm,webwork.vm
  125. 125. Incluindo conteúdo estáticocom #includeInclui um arquivo de texto qualquer,mas não faz avaliações de VTL ouvariáveis
  126. 126. Em código#include( noticias.html )#include( noticias.html , rodape.html , topo.html )
  127. 127. Incluindo templates dinâmicoscom #parseFunciona do mesmo modo que o#include, mas faz avaliação deconteúdo dinâmico em VTL
  128. 128. E agora?Acabou?Mais alguma coisa?Tá na hora de ir pegar o menino naescola?
  129. 129. Agora eu vou colocar em prática o meu plano maligno!
  130. 130. A aplicação de exemplo precisa denovas funcionalidades¡  Cadastrar, editar e listar usuários¡  Montar as mensagens de e-mail que vão ser enviadas para cada endereço
  131. 131. Trabalhem!
  132. 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. 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. 134. Trilha Sonora Arch Enemy – Doomsday MachineBlack Label Society - Mafia
  135. 135. Trilha Sonora Therion – Lemuria & Sirus BNickelback – All The Right Reasons

×