use cdi em seus projetos java !

Post on 11-Jun-2015

559 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Excelente post da CAELUM !!!

TRANSCRIPT

Porque você deveria usarCDI em todos os seus projetos Java

CDI

@sergio_caelumsergiolopes.org

CDI

(

CDI

CDI

CDI

public class ProdutoDao { public void salvar(Produto produto) {

entityManager.persist(produto); }}

public class ProdutoDao { public void salvar(Produto produto) { EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa"); EntityManager entityManager = factory.createEntityManager();

entityManager.persist(produto); }}

CDI

public class ProdutoDao {

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

public class ProdutoDao { private EntityManager entityManager;

public ProdutoDao(EntityManager em) { this.entityManager = em; }

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

public class ProdutoDao { private EntityManager entityManager; // recebo dependência pronta public ProdutoDao(EntityManager em) { this.entityManager = em; }

// uso dependência public void salvar(Produto produto) { entityManager.persist(produto); }}

injeção dedependências!

injeção dedependências!

inversão de controle.

injeção dedependências!

separação de responsabilidades.inversão de controle.

)

CDI

especificação cdiimplementação weld

public class ProdutoDao { private EntityManager entityManager;

public ProdutoDao(EntityManager em) { this.entityManager = em; }

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

public class ProdutoDao { private EntityManager entityManager; @Inject public ProdutoDao(EntityManager em) { this.entityManager = em; }

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

public class ProdutoDao {

@Inject private EntityManager entityManager;

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

CDI

injeção com @Inject

public class ProdutoController {

private ProdutoDao dao; public void insere() { Produto produto = // pega dados no request dao.salvar(produto); }}

public class ProdutoController {

@Inject private ProdutoDao dao; public void insere() { Produto produto = // pega dados no request dao.salvar(produto); }}

injeção fácil!

e oEntityManager?

CDI

métodos produtores

public class JPAUtil {

public EntityManager criaEM() {

}}

public class JPAUtil {

public EntityManager criaEM() { EntityManagerFactory factory = Persistence .createEntityManagerFactory("jpa"); return factory.createEntityManager(); }}

public class JPAUtil {

public EntityManager criaEM() { EntityManagerFactory factory = Persistence .createEntityManagerFactory("jpa"); return factory.createEntityManager(); }}

public class JPAUtil {

@Produces public EntityManager criaEM() { EntityManagerFactory factory = Persistence .createEntityManagerFactory("jpa"); return factory.createEntityManager(); }}

quando criar oEntityManager?

public class JPAUtil {

@Produces @RequestScoped public EntityManager criaEM() { EntityManagerFactory factory = Persistence .createEntityManagerFactory("jpa"); return factory.createEntityManager(); }}

mas e afactory?

public class JPAUtil {

@Produces @RequestScoped public EntityManager criaEM(){ return factory.createEntityManager(); }}

public class JPAUtil {

@Produces public EntityManagerFactory criaFactory() { return Persistence.createEntityManagerFactory("jpa"); } @Produces @RequestScoped public EntityManager criaEM(){ return factory.createEntityManager(); }}

public class JPAUtil {

@Produces public EntityManagerFactory criaFactory() { return Persistence.createEntityManagerFactory("jpa"); } @Produces @RequestScoped public EntityManager criaEM(){ return factory.createEntityManager(); }}

public class JPAUtil {

@Produces public EntityManagerFactory criaFactory() { return Persistence.createEntityManagerFactory("jpa"); } @Produces @RequestScoped public EntityManager criaEM(EntityManagerFactory factory){ return factory.createEntityManager(); }}

public class JPAUtil {

@Produces @ApplicationScoped public EntityManagerFactory criaFactory() { return Persistence.createEntityManagerFactory("jpa"); } @Produces @RequestScoped public EntityManager criaEM(EntityManagerFactory factory){ return factory.createEntityManager(); }}

e quemfecha?

public class JPAUtil {

public void fechaEM(EntityManager em) { em.close(); }

}

public class JPAUtil {

public void fechaEM(@Disposes EntityManager em) { em.close(); }

}

gerenciamentodo ciclo de vida!

e mais de umbanco de dados?

public class JPAUtil {

@Produces @ApplicationScoped public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped public EntityManager criaEM1(EntityManagerFactory factory){}

}

public class JPAUtil {

@Produces @ApplicationScoped public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped public EntityManager criaEM1(EntityManagerFactory factory){}

@Produces @ApplicationScoped public EntityManagerFactory criaFactory2() {}

@Produces @RequestScoped public EntityManager criaEM2(EntityManagerFactory factory){} }

public class JPAUtil {

@Produces @ApplicationScoped public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped public EntityManager criaEM1(EntityManagerFactory factory){}

@Produces @ApplicationScoped public EntityManagerFactory criaFactory2() {}

@Produces @RequestScoped public EntityManager criaEM2(EntityManagerFactory factory){} }

?

CDI

qualifiers

public class JPAUtil {

@Produces @ApplicationScoped @Geral public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped public EntityManager criaEM1(EntityManagerFactory factory){}

@Produces @ApplicationScoped @Diretor public EntityManagerFactory criaFactory2() {}

@Produces @RequestScoped public EntityManager criaEM2(EntityManagerFactory factory){} }

public class JPAUtil {

@Produces @ApplicationScoped @Geral public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped public EntityManager criaEM1(@Geral EntityManagerFactory f){}

@Produces @ApplicationScoped @Diretor public EntityManagerFactory criaFactory2() {}

@Produces @RequestScoped public EntityManager criaEM2(@Diretor EntityManagerFactory f){} }

@Retention(RUNTIME)public @interface Diretor {}

@Retention(RUNTIME)public @interface Geral {}

@Qualifier@Retention(RUNTIME)public @interface Diretor {}

@Qualifier@Retention(RUNTIME)public @interface Geral {}

public class ProdutoDao {

@Inject private EntityManager entityManager;

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

public class ProdutoDao {

@Inject @Geral private EntityManager entityManager;

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

public class JPAUtil {

@Produces @ApplicationScoped @Geral public EntityManagerFactory criaFactory1() {}

@Produces @RequestScoped @Geral public EntityManager criaEM1(@Geral EntityManagerFactory f){}

@Produces @ApplicationScoped @Diretor public EntityManagerFactory criaFactory2() {}

@Produces @RequestScoped @Diretor public EntityManager criaEM2(@Diretor EntityManagerFactory f){} }

public class BackupDeTudo {

public void backupBDs() {

}}

public class BackupDeTudo {

@Inject @Any private Instance<EntityManager> todosEntityMangers; public void backupBDs() {

}}

public class BackupDeTudo {

@Inject @Any private Instance<EntityManager> todosEntityMangers; public void backupBDs() { for (EntityManager em : todosEntityMangers) { // ... } }}

múltiplosbeans!

quem controlatransações?

public class ProdutoDao { @Inject private EntityManager entityManager; public void salvar(Produto produto) { entityManager.getTransaction().begin(); entityManager.persist(produto); entityManager.getTransaction().commit(); }

}

public class ProdutoDao { @Inject private EntityManager entityManager; public void salvar(Produto produto) { entityManager.getTransaction().begin(); entityManager.persist(produto); entityManager.getTransaction().commit(); } public void apagar(Produto produto) { entityManager.getTransaction().begin(); entityManager.remove(produto); entityManager.getTransaction().commit(); }}

public class ProdutoDao { @Inject private EntityManager entityManager; public void salvar(Produto produto) { entityManager.getTransaction().begin(); entityManager.persist(produto); entityManager.getTransaction().commit(); } public void apagar(Produto produto) { entityManager.getTransaction().begin(); entityManager.remove(produto); entityManager.getTransaction().commit(); }}

public class ProdutoController {

@Inject private ProdutoDao dao; public void substitui() { dao.salvar(produtoNovo); dao.apagar(produtoAntigo); }}

CDI

interceptadores

public class ProdutoController {

@Inject private ProdutoDao dao; @Transacional public void substitui() { dao.salvar(produtoNovo); dao.apagar(produtoAntigo); }}

@InterceptorBinding@Retention(RUNTIME)public @interface Transacional { }

public class ProdutoDao { @Inject private EntityManager entityManager; public void salvar(Produto produto) { entityManager.persist(produto); } public void apagar(Produto produto) { entityManager.remove(produto); }}

@Interceptor @Transacionalpublic class TransacionalInterceptor {

}

@Interceptor @Transacionalpublic class TransacionalInterceptor {

@AroundInvoke public Object intercept(InvocationContext ctx) {

}}

@Interceptor @Transacionalpublic class TransacionalInterceptor {

@AroundInvoke public Object intercept(InvocationContext ctx) { // ... antes da lógica

Object resultado = ctx.proceed();

// ... depois da lógica return resultado; }}

@Interceptor @Transacionalpublic class TransacionalInterceptor {

@Inject private EntityManager em;

@AroundInvoke public Object intercept(InvocationContext ctx) { em.getTransaction().begin();

Object resultado = ctx.proceed();

em.getTransaction().commit(); return resultado; }}

<beans> <interceptors> <class> br.com.caelum.TransacionalInterceptor </class> </interceptors></beans>

maisencapsulado!

um processo decompra complexo

public class Pagamento {

public void efetuaCobranca() { // ... comunica com Cielo }}

public class Estoque {

public void reservaMercadoria() { // ... reserva produto no estoque }}

public class Notificacoes {

public void notificaCompra() { // envia email confirmando pro usuario }}

public class FinalizaCompraController {

public void finalizaCompra() {

}}

public class FinalizaCompraController {

@Inject private Pagamento pagamento;

public void finalizaCompra() { pagamento.efetuaCobranca();

}}

public class FinalizaCompraController {

@Inject private Pagamento pagamento; @Inject private Estoque estoque;

public void finalizaCompra() { pagamento.efetuaCobranca(); estoque.reservaMercadoria();

}}

public class FinalizaCompraController {

@Inject private Pagamento pagamento; @Inject private Estoque estoque; @Inject private Notificacoes notificacoes; public void finalizaCompra() { pagamento.efetuaCobranca(); estoque.reservaMercadoria(); notificacoes.notificaCompra(); }}

como desacoplaro processo?

CDI

eventos

public class FinalizaCompraController {

public void finalizaCompra() {

}}

public class FinalizaCompraController {

public void finalizaCompra() { Compra compra = new Compra(produto, cliente);

}}

public class FinalizaCompraController {

@Inject @Any private Event<Compra> eventoCompra; public void finalizaCompra() { Compra compra = new Compra(produto, cliente);

}}

public class FinalizaCompraController {

@Inject @Any private Event<Compra> eventoCompra; public void finalizaCompra() { Compra compra = new Compra(produto, cliente); eventoCompra.fire(compra); }}

public class Pagamento {

public void efetuaCobranca(Compra c) { // ... comunica com Cielo }}

public class Pagamento {

public void efetuaCobranca(@Observes Compra c) { // ... comunica com Cielo }}

public class Pagamento {

public void efetuaCobranca(@Observes Compra c) { // ... comunica com Cielo }}public class Estoque {

public void reservaMercadoria(@Observes Compra c) { // ... reserva produto no estoque }}

maisdesacoplado!

não quero cobraro cartão em teste

public class Pagamento {

public void efetuaCobranca(@Observes Compra c) {WebServiceCielo.cobraDeVerdade(c.getCartao());

}}

CDI

alternatives

public class PagamentoDeVerdade {

}

public class PagamentoDeMentira {

}

public class PagamentoDeVerdade {

public void efetuaCobranca(@Observes Compra c) {

}}

public class PagamentoDeMentira {

public void efetuaCobranca(@Observes Compra c) {

}}

public class PagamentoDeVerdade {

public void efetuaCobranca(@Observes Compra c) {WebServiceCielo.cobraDeVerdade(c.getCartao());

}}

public class PagamentoDeMentira {

public void efetuaCobranca(@Observes Compra c) { LogDeTeste.fariaUmaCompraAqui(); }}

public class PagamentoDeVerdade implements Pagamento {

public void efetuaCobranca(@Observes Compra c) {WebServiceCielo.cobraDeVerdade(c.getCartao());

}}

public class PagamentoDeMentira implements Pagamento {

public void efetuaCobranca(@Observes Compra c) { LogDeTeste.fariaUmaCompraAqui(); }}

public class PagamentoDeVerdade implements Pagamento {

public void efetuaCobranca(@Observes Compra c) {WebServiceCielo.cobraDeVerdade(c.getCartao());

}}

@Alternativepublic class PagamentoDeMentira implements Pagamento {

public void efetuaCobranca(@Observes Compra c) { LogDeTeste.fariaUmaCompraAqui(); }}

<beans> <alternatives> <class> br.com.caelum.PagamentoDeMentira </class> </alternatives></beans>

CDI

extensions spi

posso estendero próprio CDI!

public class HelloExtension implements Extension {

}

public class HelloExtension implements Extension {

<T> void hiBean(@Observes ProcessAnnotatedType<T> pat) {

}}

public class HelloExtension implements Extension {

<T> void hiBean(@Observes ProcessAnnotatedType<T> pat) { Class<T> clazz = pat.getAnnotatedType().getJavaClass(); System.out.println("Hi! " + clazz.getName()); }}

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

br.com.caelum.HelloExtension

posso modificaros beans do CDI

public class ModulosOpcionaisExtension implements Extension{

}

public class ModulosOpcionaisExtension implements Extension{

<T> void bloqueia(@Observes ProcessAnnotatedType<T> pat) {

}

}

public class ModulosOpcionaisExtension implements Extension{

<T> void bloqueia(@Observes ProcessAnnotatedType<T> pat) { Class<T> clazz = pat.getAnnotatedType().getJavaClass(); String packageName = clazz.getPackage().getName();

}

}

public class ModulosOpcionaisExtension implements Extension{

<T> void bloqueia(@Observes ProcessAnnotatedType<T> pat) { Class<T> clazz = pat.getAnnotatedType().getJavaClass(); String packageName = clazz.getPackage().getName(); if (deveSerBloqueado(packageName)) {

} }

private boolean deveSerBloqueado(String pkg) { // TODO ler um arquivo de config de módulos bloqueados? return pkg.startsWith("br.com.caelum.entrega"); }}

public class ModulosOpcionaisExtension implements Extension{

<T> void bloqueia(@Observes ProcessAnnotatedType<T> pat) { Class<T> clazz = pat.getAnnotatedType().getJavaClass(); String packageName = clazz.getPackage().getName(); if (deveSerBloqueado(packageName)) { pat.veto(); } }

private boolean deveSerBloqueado(String pkg) { // TODO ler um arquivo de config de módulos bloqueados? return pkg.startsWith("br.com.caelum.entrega"); }}

dá pra estendermuito mais

decoratorsstereotypesinjection pointscustom scopesconversation scopemais de extensions

CDI+

Você deveria usarCDI em todos os seus projetos Java!

CDI

Obrigado!@sergio_caelum

top related