+ All Categories
Home > Technology > CDI do básico ao avançado

CDI do básico ao avançado

Date post: 11-May-2015
Category:
Upload: alberto-souza
View: 1,980 times
Download: 8 times
Share this document with a friend
Popular Tags:
73
CDI, do básico ao avançado Thursday, September 5, 13
Transcript
Page 1: CDI do básico ao avançado

CDI, do básico ao avançado

Thursday, September 5, 13

Page 2: CDI do básico ao avançado

Alberto Souza

• @alberto_souza

• github.com/asouza

Thursday, September 5, 13

Page 3: CDI do básico ao avançado

Usar ou criar?

@ManagedBeanpublic class ProdutosBean {

@PostConstruct public void carregaProdutos(){ ProdutoDAO produtos = new ProdutoDAO(); produtos.setConnection(ConnectionFactory.createConnection()); this.lista = dao.lista(); }}

Thursday, September 5, 13

Page 4: CDI do básico ao avançado

Usar!

@ManagedBeanpublic class ProdutosBean { private ProdutoDAO produtos; private ProdutosBean(ProdutoDAO produtos){ this.produtos = produtos; }

@PostConstruct public void carregaProdutos(){ this.lista = dao.lista(); }}

Thursday, September 5, 13

Page 5: CDI do básico ao avançado

Injeção de Dependências

• JAVAEE 6/7

• CDI 1.0/1.1

• WELD 2

Thursday, September 5, 13

Page 6: CDI do básico ao avançado

Uso fácil

@ManagedBeanpublic class ProdutosBean { @Inject private ProdutoDAO produtos; @PostConstruct public void carregaProdutos(){ return dao.lista(); }}

Thursday, September 5, 13

Page 7: CDI do básico ao avançado

Injeção de Dependências

• E como configura?

Thursday, September 5, 13

Page 8: CDI do básico ao avançado

Injeção de Dependências

• Não precisa mais

Thursday, September 5, 13

Page 9: CDI do básico ao avançado

Outro exemplo

class ProdutoDAO{ @Inject private EntityManager em; public List<Produto> lista(){ return em.createQuery("select p from Produto p"); }}

Thursday, September 5, 13

Page 10: CDI do básico ao avançado

Criação de EntityManager

EntityManagerFactory emf = Persistence. createEntityManagerFactory("loja"); EntityManager em = emf.createEntityManager();

Thursday, September 5, 13

Page 11: CDI do básico ao avançado

Tem que ensinar

class EntityManagerProducer{private EntityManagerFactory emf = Persistence.createEntityManagerFactory("loja"); @Produces public EntityManager create(){ return factory.createEntityManager(); }}

Thursday, September 5, 13

Page 12: CDI do básico ao avançado

Escopo?

class EntityManagerProducer{private EntityManagerFactory emf = Persistence.createEntityManagerFactory("loja"); @Produces @RequestScoped public EntityManager create(){ return factory.createEntityManager(); }}

Thursday, September 5, 13

Page 13: CDI do básico ao avançado

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

Page 14: CDI do básico ao avançado

Qual é o remetente?

public class FinalizadorDeCompra{ private String remetente; public void envia(){ mailer.send(remente,...); }}

Thursday, September 5, 13

Page 15: CDI do básico ao avançado

Trocar a injeção de String?

public class FinalizadorDeCompra{ @Inject private String remetente; public void envia(){ mailer.send(remente,...); }}

Thursday, September 5, 13

Page 16: CDI do básico ao avançado

Só quero para determinada String

public class FinalizadorDeCompra{ @Inject @RemetenteCompra private String remetente; public void envia(){ mailer.send(remente,...); }}

Thursday, September 5, 13

Page 17: CDI do básico ao avançado

Qualifier

//outras annotations chatas@Qualifier@interface RemetenteCompra{}

Thursday, September 5, 13

Page 18: CDI do básico ao avançado

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

Page 19: CDI do básico ao avançado

Indo além

• VRaptor CDI e integração com o Container

Thursday, September 5, 13

Page 20: CDI do básico ao avançado

Injeção de coisas do container

• Quero usar um EJB, EntityManager...

Thursday, September 5, 13

Page 21: CDI do básico ao avançado

Injeção de coisas do container

@Componentpublic class ProdutoDAO { @Inject private final EntityManager entityManager;

public void salva(Produto produto) { entityManager.persist(produto); }

Thursday, September 5, 13

Page 22: CDI do básico ao avançado

Injeção de coisas do container

@Stateless @Componentpublic class ProdutoDAO { @Inject private final EntityManager entityManager;

public void salva(Produto produto) { entityManager.persist(produto); }

Thursday, September 5, 13

Page 23: CDI do básico ao avançado

Injeção de coisas do container

@Resourcepublic class ProdutosController {

//@EJB @Inject private ProdutoDAO produtoDAO; ...}

Thursday, September 5, 13

Page 24: CDI do básico ao avançado

EJB?

• Por sinal o DAO é um EJB porque?

Thursday, September 5, 13

Page 25: CDI do básico ao avançado

EJB?

@Componentpublic class ProdutoDAO { @Inject private final EntityManager entityManager;

@Transactional public void salva(Produto produto) { entityManager.persist(produto); }

Thursday, September 5, 13

Page 26: CDI do básico ao avançado

Exemplo de uso

• Coloco no interceptor e tá tudo certo!

Thursday, September 5, 13

Page 27: CDI do básico ao avançado

Componente padrão

@RequestScopedpublic 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

Page 28: CDI do básico ao avançado

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

Page 29: CDI do básico ao avançado

Alternative

@Alternativeclass 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

Page 30: CDI do básico ao avançado

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

Page 31: CDI do básico ao avançado

ilhazinha

• Alternative habilitado só no bean archive

Thursday, September 5, 13

Page 32: CDI do básico ao avançado

ilhazinha

• VRaptor não enxergava

Thursday, September 5, 13

Page 33: CDI do básico ao avançado

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

Page 34: CDI do básico ao avançado

Prioridade

• Podemos sempre sobreescrever!

Thursday, September 5, 13

Page 35: CDI do básico ao avançado

Servidor já injeta Request

• Request do VRaptor é modificado

Thursday, September 5, 13

Page 36: CDI do básico ao avançado

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

Page 37: CDI do básico ao avançado

Aproveitamos o existente

@Decoratorpublic 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

Page 38: CDI do básico ao avançado

Configuramos

<decorators> <class>br.com.caelum.vraptor.http.VRaptorRequest</class> </decorators>

Thursday, September 5, 13

Page 39: CDI do básico ao avançado

Priority

• Pode usar Priority também!

Thursday, September 5, 13

Page 40: CDI do básico ao avançado

Injetar Requestspublic 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

Page 41: CDI do básico ao avançado

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

Page 42: CDI do básico ao avançado

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

Page 43: CDI do básico ao avançado

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

Page 44: CDI do básico ao avançado

VRaptor já tem @RequestScoped

public @interface RequestScoped {}

Thursday, September 5, 13

Page 45: CDI do básico ao avançado

Eu sou você!

@[email protected]@Namedpublic @interface RequestScoped {}

Thursday, September 5, 13

Page 46: CDI do básico ao avançado

VRaptor não usa @Inject

@Resourcepublic class ProdutoDAO {

private final EntityManager entityManager;

public CDIResourceComponent(EntityManager entityManager) { this.entityManager = entityManager; }

}

Thursday, September 5, 13

Page 47: CDI do básico ao avançado

Oxi, sem @Inject?

• Cadê o @Inject?

Thursday, September 5, 13

Page 48: CDI do básico ao avançado

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

Page 49: CDI do básico ao avançado

VRaptor já tem Factories

@Componentpublic 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

Page 50: CDI do básico ao avançado

Oxi, e o @Produces?

• E o @Produces?

Thursday, September 5, 13

Page 51: CDI do básico ao avançado

@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

Page 52: CDI do básico ao avançado

Configura extensão

• META-INF/services/javax.enterprise.inject.spi.Extension

Thursday, September 5, 13

Page 53: CDI do básico ao avançado

Configura extensão

br.com.caelum.vraptor.ioc.cdi.extensions.AddInjectToConstructorExtension

br.com.caelum.vraptor.ioc.cdi.extensions.ComponentFactoryExtension

Thursday, September 5, 13

Page 54: CDI do básico ao avançado

E para testar?

• E para testar?

Thursday, September 5, 13

Page 55: CDI do básico ao avançado

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

Page 56: CDI do básico ao avançado

Arquillian

public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addPackage("com.thoughtworks.xstream") }

Thursday, September 5, 13

Page 57: CDI do básico ao avançado

Problemas

• Falta de controle sobre o container

Thursday, September 5, 13

Page 58: CDI do básico ao avançado

DeltaSpike

cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot();

Thursday, September 5, 13

Page 59: CDI do básico ao avançado

Controle do escopo

public void start(Class<? extends Annotation> scope) { cdiContainer.getContextControl().startContext(scope); }

Thursday, September 5, 13

Page 60: CDI do básico ao avançado

Controle do escopo

start(RequestScoped.class); start(SessionScoped.class); //logica stop(SessionScoped.class); stop(RequestScoped.class);

Thursday, September 5, 13

Page 61: CDI do básico ao avançado

Últimos detalhes

• Funcionalidade com muitos passos

Thursday, September 5, 13

Page 62: CDI do básico ao avançado

Funcionalidade com vários passos

@Controllerpublic 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

Page 63: CDI do básico ao avançado

Funcionalidade com vários passos

@Controllerpublic 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

Page 64: CDI do básico ao avançado

Como implementar?

• 2 Maneiras?

Thursday, September 5, 13

Page 65: CDI do básico ao avançado

Exemplo de implementação

• Stateless?

Thursday, September 5, 13

Page 66: CDI do básico ao avançado

Outro exemplo

• Stateful?

Thursday, September 5, 13

Page 67: CDI do básico ao avançado

Meio termo

• Mangue moderado!

Thursday, September 5, 13

Page 68: CDI do básico ao avançado

Conversation

@Controller @ConversationScopedpublic 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

Page 69: CDI do básico ao avançado

Conversation

@Controller @ConversationScopedpublic 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

Page 70: CDI do básico ao avançado

Conversation

@Controller @ConversationScopedpublic class PagamentoController implements Serializable{ @Inject public PagamentoController(Result result) { super(); this.result = result; }

Thursday, September 5, 13

Page 71: CDI do básico ao avançado

E esse result?

• O Result tem que ser passivavel :(

Thursday, September 5, 13

Page 72: CDI do básico ao avançado

Não mais :)

@Controller @ConversationScopedpublic class PagamentoController implements Serializable{ @Inject public PagamentoController(@TransientReference Result result) { super(); this.result = result; }

Thursday, September 5, 13

Page 73: CDI do básico ao avançado

Valeu! @alberto_souza

github.com/asouza

Thursday, September 5, 13


Recommended