CDI do básico ao avançado
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

CDI do básico ao avançado

on

  • 1,642 views

 

Statistics

Views

Total Views
1,642
Views on SlideShare
1,633
Embed Views
9

Actions

Likes
4
Downloads
39
Comments
0

1 Embed 9

https://twitter.com 9

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

CDI do básico ao avançado Presentation Transcript

  • 1. CDI, do básico ao avançado Thursday, September 5, 13
  • 2. Alberto Souza • @alberto_souza • github.com/asouza Thursday, September 5, 13
  • 3. Usar ou criar? @ManagedBean public class ProdutosBean { @PostConstruct public void carregaProdutos(){ ProdutoDAO produtos = new ProdutoDAO(); produtos.setConnection(ConnectionFactory.createConnection()); this.lista = dao.lista(); } } Thursday, September 5, 13
  • 4. Usar! @ManagedBean public class ProdutosBean { private ProdutoDAO produtos; private ProdutosBean(ProdutoDAO produtos){ this.produtos = produtos; } @PostConstruct public void carregaProdutos(){ this.lista = dao.lista(); } } Thursday, September 5, 13
  • 5. Injeção de Dependências • JAVAEE 6/7 • CDI 1.0/1.1 • WELD 2 Thursday, September 5, 13
  • 6. Uso fácil @ManagedBean public class ProdutosBean { @Inject private ProdutoDAO produtos; @PostConstruct public void carregaProdutos(){ return dao.lista(); } } Thursday, September 5, 13
  • 7. Injeção de Dependências • E como configura? Thursday, September 5, 13
  • 8. Injeção de Dependências • Não precisa mais Thursday, September 5, 13
  • 9. Outro exemplo class ProdutoDAO{ @Inject private EntityManager em; public List<Produto> lista(){ return em.createQuery("select p from Produto p"); } } Thursday, September 5, 13
  • 10. Criação de EntityManager EntityManagerFactory emf = Persistence. createEntityManagerFactory("loja"); EntityManager em = emf.createEntityManager(); Thursday, September 5, 13
  • 11. Tem que ensinar class EntityManagerProducer{ private EntityManagerFactory emf = Persistence.createEntityManagerFactory("loja"); @Produces public EntityManager create(){ return factory.createEntityManager(); } } Thursday, September 5, 13
  • 12. Escopo? class EntityManagerProducer{ private EntityManagerFactory emf = Persistence.createEntityManagerFactory("loja"); @Produces @RequestScoped public EntityManager create(){ return factory.createEntityManager(); } } Thursday, September 5, 13
  • 13. Escopo? class EntityManagerProducer{ private EntityManagerFactory emf = Persistence.createEntityManagerFactory("loja"); //outro método aqui... public void close(@Disposes EntityManager entityManager){ entityManager.close(); } } Thursday, September 5, 13
  • 14. Qual é o remetente? public class FinalizadorDeCompra{ private String remetente; public void envia(){ mailer.send(remente,...); } } Thursday, September 5, 13
  • 15. Trocar a injeção de String? public class FinalizadorDeCompra{ @Inject private String remetente; public void envia(){ mailer.send(remente,...); } } Thursday, September 5, 13
  • 16. Só quero para determinada String public class FinalizadorDeCompra{ @Inject @RemetenteCompra private String remetente; public void envia(){ mailer.send(remente,...); } } Thursday, September 5, 13
  • 17. Qualifier //outras annotations chatas @Qualifier @interface RemetenteCompra{ } Thursday, September 5, 13
  • 18. Qualifier @ApplicationScoped class RemetentesProducer { @Produces @RemetenteCompra public String remetenteCompra(){ return properties.getProperty("remetente.compra"); } @Produces @RemetenteNewsletter public String remetenteNewsletter(){ return properties.getProperty("remetente.newsletter"); } } Thursday, September 5, 13
  • 19. Indo além • VRaptor CDI e integração com o Container Thursday, September 5, 13
  • 20. Injeção de coisas do container • Quero usar um EJB, EntityManager... Thursday, September 5, 13
  • 21. Injeção de coisas do container @Component public class ProdutoDAO { @Inject private final EntityManager entityManager; public void salva(Produto produto) { entityManager.persist(produto); } Thursday, September 5, 13
  • 22. Injeção de coisas do container @Stateless @Component public class ProdutoDAO { @Inject private final EntityManager entityManager; public void salva(Produto produto) { entityManager.persist(produto); } Thursday, September 5, 13
  • 23. Injeção de coisas do container @Resource public class ProdutosController { //@EJB @Inject private ProdutoDAO produtoDAO; ... } Thursday, September 5, 13
  • 24. EJB? • Por sinal o DAO é um EJB porque? Thursday, September 5, 13
  • 25. EJB? @Component public class ProdutoDAO { @Inject private final EntityManager entityManager; @Transactional public void salva(Produto produto) { entityManager.persist(produto); } Thursday, September 5, 13
  • 26. Exemplo de uso • Coloco no interceptor e tá tudo certo! Thursday, September 5, 13
  • 27. Componente padrão @RequestScoped public class DefaultPathResolver implements PathResolver { public String pathFor(ResourceMethod method) { String format = resolver.getAcceptFormat(); String suffix = ""; if (format != null && !format.equals("html")) { suffix = "." + format; } //WEB-INF/jsp/controller/metodo.jsp String name = method.getResource().getType().getSimpleName(); String folderName = extractControllerFromName(name); return getPrefix() + folderName + "/" + method.getMethod().getName() + suffix + "."+getExtension(); } Thursday, September 5, 13
  • 28. Componente customizado class CustomPathResolver implements PathResolver{ public String pathFor(ResourceMethod method) { String format = resolver.getAcceptFormat(); String suffix = ""; if (format != null && !format.equals("html")) { suffix = "." + format; } //WEB-INF/resources/controller/metodo.jsp String name = method.getResource().getType().getSimpleName(); String folderName = extractControllerFromName(name); return "WEB-INF/resources" + folderName + "/" + method.getMethod().getName() + suffix + "."+getExtension(); } } Thursday, September 5, 13
  • 29. Alternative @Alternative class CustomPathResolver implements PathResolver{ public String pathFor(ResourceMethod method) { String format = resolver.getAcceptFormat(); String suffix = ""; if (format != null && !format.equals("html")) { suffix = "." + format; } //WEB-INF/jsp/controller/metodo.jsp String name = method.getResource().getType().getSimpleName(); String folderName = extractControllerFromName(name); return "WEB-INF/resources" + folderName + "/" + method.getMethod().getName() + suffix + "."+getExtension(); } } Thursday, September 5, 13
  • 30. Registra no beans.xml <?xml version="1.0" encoding="UTF-8"?> <beans> <alternatives> <class>br.com.caelum.vraptor.view.CustomPathResolver</class> </alternatives> </beans> Thursday, September 5, 13
  • 31. ilhazinha • Alternative habilitado só no bean archive Thursday, September 5, 13
  • 32. ilhazinha • VRaptor não enxergava Thursday, September 5, 13
  • 33. Prioridade @Alternative @Priority(Interceptor.Priority.APPLICATION) class CustomPathResolver implements PathResolver{ public String pathFor(ResourceMethod method) { String format = resolver.getAcceptFormat(); String suffix = ""; if (format != null && !format.equals("html")) { suffix = "." + format; } //WEB-INF/jsp/controller/metodo.jsp String name = method.getResource().getType().getSimpleName(); String folderName = extractControllerFromName(name); return "WEB-INF/resources" + folderName + "/" + method.getMethod().getName() + suffix + "."+getExtension(); } } Thursday, September 5, 13
  • 34. Prioridade • Podemos sempre sobreescrever! Thursday, September 5, 13
  • 35. Servidor já injeta Request • Request doVRaptor é modificado Thursday, September 5, 13
  • 36. Aproveita o que já existe public class VRaptorRequest implements MutableRequest,HttpServletRequest { private final Hashtable<String, String[]> extraParameters = new Hashtable<String, String[]>(); //qual que ele vai injetar? @Inject private HttpServletRequest request; } Thursday, September 5, 13
  • 37. Aproveitamos o existente @Decorator public class VRaptorRequest implements MutableRequest,HttpServletRequest { @Delegate private HttpServletRequest delegate; @Override public String getParameter(String name) { if (extraParameters.containsKey(name)) { String[] values = extraParameters.get(name); if (values.length == 1) { return values[0]; } else { return Arrays.toString(values); } } return delegate.getParameter(name); } Thursday, September 5, 13
  • 38. Configuramos <decorators> <class>br.com.caelum.vraptor.http.VRaptorRequest</class> </decorators> Thursday, September 5, 13
  • 39. Priority • Pode usar Priority também! Thursday, September 5, 13
  • 40. Injetar Requests public class DefaultFormatResolver implements FormatResolver { private final HttpServletRequest request; private final AcceptHeaderToFormat acceptHeaderToFormat; @Inject public DefaultFormatResolver(HttpServletRequest request, AcceptHeaderToFormat acceptHeaderToFormat) { this.request = request; this.acceptHeaderToFormat = acceptHeaderToFormat; } public String getAcceptFormat() { String format = request.getParameter("_format"); if (format != null) { return format; } format = request.getHeader("Accept"); Thursday, September 5, 13
  • 41. Trocar o request o tempo todo @Inject private CDIHttpServletRequestFactory requestFactory; @Inject private CDIHttpSessionFactory sessionFactory; public <T> T provideForRequest(RequestInfo request) { //configurando produtores requestFactory.setRequest(request); sessionFactory.setSession(request); return execution.insideRequest(container); } Thursday, September 5, 13
  • 42. Notifica o povo @Inject private Event<HttpServletRequest> eventosDeRequest; public <T> T provideForRequest(RequestInfo requestInfo, Execution<T> execution) { //configurando produtores eventosDeRequest.fire(requestInfo.getRequest()); return execution.insideRequest(container); } Thursday, September 5, 13
  • 43. Quero ser notificado public class CDIHttpServletRequestFactory implements ComponentFactory<HttpServletRequest>{ private HttpServletRequest request; public void handle(@Observes HttpServletRequest request){ this.request = request; } public HttpServletRequest getInstance(){ return request; } } Thursday, September 5, 13
  • 44. VRaptor já tem @RequestScoped public @interface RequestScoped { } Thursday, September 5, 13
  • 45. Eu sou você! @Stereotype @javax.enterprise.context.RequestScoped @Named public @interface RequestScoped { } Thursday, September 5, 13
  • 46. VRaptor não usa @Inject @Resource public class ProdutoDAO { private final EntityManager entityManager; public CDIResourceComponent(EntityManager entityManager) { this.entityManager = entityManager; } } Thursday, September 5, 13
  • 47. Oxi, sem @Inject? • Cadê o @Inject? Thursday, September 5, 13
  • 48. Pedimos a ele para colocar public class AddInjectToConstructorExtension implements Extension{ public void processAnnotatedType(@Observes final ProcessAnnotatedType pat) { AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(pat.getAnnotatedType()); if (hasArgsConstructorAndNoInjection) { Constructor constructor = constructors.get(0); //pulo do gato builder.addToConstructor(constructor,new AnnotationLiteral<Inject>() {}); //trocando a configuração original pat.setAnnotatedType(builder.create()); } } Thursday, September 5, 13
  • 49. VRaptor já tem Factories @Component public class CDIComponent implements ComponentFactory { private final MyRequestComponent component; public CDIComponent(MyRequestComponent component) { this.component = component; } public ComponentToBeProduced getInstance() { return new ComponentToBeProduced(); } } Thursday, September 5, 13
  • 50. Oxi, e o @Produces? • E o @Produces? Thursday, September 5, 13
  • 51. @Produces em cima do método public class ComponentFactoryExtension implements Extension{ public void addProduces(@Observes ProcessAnnotatedType pat) { builder.readFromType(pat.getAnnotatedType()); if (ComponentFactory.class.isAssignableFrom(javaClass)) { builder.addToMethod(getInstance,new ProducesAnnotion()); } } } class ProducesAnnotion extends AnnotationLiteral<Produces>{ } Thursday, September 5, 13
  • 52. Configura extensão • META-INF/services/ javax.enterprise.inject.spi.Extension Thursday, September 5, 13
  • 53. Configura extensão br.com.caelum.vraptor.ioc.cdi.extensions.AddInjectToConstructorExtensi on br.com.caelum.vraptor.ioc.cdi.extensions.ComponentFactoryExtension Thursday, September 5, 13
  • 54. E para testar? • E para testar? Thursday, September 5, 13
  • 55. Arquillian @RunWith(Arquillian.class) public class CDIProviderRegisteringComponentsTest { @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(DefaultPathResolver.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } Thursday, September 5, 13
  • 56. Arquillian public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addPackage("com.thoughtworks.xstream") } Thursday, September 5, 13
  • 57. Problemas • Falta de controle sobre o container Thursday, September 5, 13
  • 58. DeltaSpike cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); Thursday, September 5, 13
  • 59. Controle do escopo public void start(Class<? extends Annotation> scope) { cdiContainer.getContextControl().startContext(scope); } Thursday, September 5, 13
  • 60. Controle do escopo start(RequestScoped.class); start(SessionScoped.class); //logica stop(SessionScoped.class); stop(RequestScoped.class); Thursday, September 5, 13
  • 61. Últimos detalhes • Funcionalidade com muitos passos Thursday, September 5, 13
  • 62. Funcionalidade com vários passos @Controller public class PagamentoController implements Serializable{ private InformacoesDoComprador info = new InformacoesDoComprador(); @Inject public PagamentoController(Result result) { super(); this.result = result; } @Post("compra/endereco") public void associaEndereco(String endereco){ info.setEnderecoDeEntrega(endereco); } Thursday, September 5, 13
  • 63. Funcionalidade com vários passos @Controller public class PagamentoController implements Serializable{ //resto que não coube e eu não soube ajeitar. @Post("compra/endereco") public void associaEndereco(String endereco){ info.setEnderecoDeEntrega(endereco); } @Post("compra/cartao") public void associaCartao(String numero){ //como mantém as informações do comprador? info.setNumeroDoCartao(numero); result.include("dadosComprador",info); } } Thursday, September 5, 13
  • 64. Como implementar? • 2 Maneiras? Thursday, September 5, 13
  • 65. Exemplo de implementação • Stateless? Thursday, September 5, 13
  • 66. Outro exemplo • Stateful? Thursday, September 5, 13
  • 67. Meio termo • Mangue moderado! Thursday, September 5, 13
  • 68. Conversation @Controller @ConversationScoped public class PagamentoController implements Serializable{ @Inject private Conversation conversation; @Post("compra/endereco") public void associaEndereco(String endereco){ conversation.begin(); info.setEnderecoDeEntrega(endereco); result.redirectTo("/compra/cartao? cid="+conversation.getId()); } Thursday, September 5, 13
  • 69. Conversation @Controller @ConversationScoped public class PagamentoController implements Serializable{ @Inject private Conversation conversation; @Post("compra/cartao") public void associaCartao(String numero){ info.setNumeroDoCartao(numero); //grava e vamo aí.. conversation.end(); result.include("dadosComprador",info); } Thursday, September 5, 13
  • 70. Conversation @Controller @ConversationScoped public class PagamentoController implements Serializable{ @Inject public PagamentoController(Result result) { super(); this.result = result; } Thursday, September 5, 13
  • 71. E esse result? • O Result tem que ser passivavel :( Thursday, September 5, 13
  • 72. Não mais :) @Controller @ConversationScoped public class PagamentoController implements Serializable{ @Inject public PagamentoController(@TransientReference Result result) { super(); this.result = result; } Thursday, September 5, 13
  • 73. Valeu! @alberto_souza github.com/asouza Thursday, September 5, 13