Desenvolvendo uma aplicação Desktop com Weld – Final

Depois da parte 1 e parte 2, chegamos à parte final do nosso exemplo. Disponibilizei o código e vou mostrar mais algumas coisas.
Só uma observação sobre o código: é o mesmo utilizado na apresentação de 14 de Novembro de 2009, quando ainda não tínhamos as mesmas versões de hoje. Mas o exemplo é totalmente funcional. Acabei deixando fixa a versão no pom.xml, então para testar a última versão você vai ter que alterá-lo.

Agora voltando ao post…


Alternatives


Alternatives são a forma de trocarmos um objeto por outro. É parecido com um decorator, mas em vez de incrementar funcionalidades, um alternative serve para substituir um bean.

No nosso exemplo, temos o seguinte objeto como alternativa ao nosso CaixaEletronico:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Alternative
public class CaixaEletronicoSubstituto extends CaixaEletronico{
 
 
	public void depositar(float valor)
	{
		System.out.println("@@@@@@ CaixaEletronicoMock.depositar():" + valor);
	}
	public void sacar(float valor)
	{
		System.out.println("@@@@@@ CaixaEletronicoMock.sacar():" + valor);
	}
}


E para habilitar temos que mudar novamente nosso META-INF/beans.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
 
	<interceptors>
		<class>br.com.jugms.weldse.intercept.ContaInterceptor</class>
	</interceptors>
 
	<decorators>
		<class>br.com.jugms.weldse.intercept.CaixaDecorator</class>
	</decorators>
 
	<alternatives>
		<class>br.com.jugms.weldse.model.CaixaEletronicoSubstituto</class>
	</alternatives>
 
</beans>


Agora se executarmos nosso código a saída sera:

hello
CaixaDecorator.sacar()
@@@@@@ CaixaEletronicoMock.sacar():200.0
ContaInterceptor.protege(antes) >> getSaldo
ContaInterceptor.protege(depois) >> getSaldo
2000.0
CaixaDecorator.depositar()
@@@@@@ CaixaEletronicoMock.depositar():300.0
ContaInterceptor.protege(antes) >> getSaldo
ContaInterceptor.protege(depois) >> getSaldo
2000.0


Como podemos ver, nosso decorator decora o alternative e o interceptor continua funcionando normalmente.
Podemos também declarar uma anotação própria e anotá-la como alternative. Mas em vez de tentar explicar, vou mostrar um outro exemplo que servirá como base para este.


Estereótipos próprios


Podemos criar nossos próprios estereótipos, e dessa forma não só reduzir a quantidade de anotações em cima dos nossos beans, mas também deixar a leitura das anotações mais condizentes com nosso linguajar do dia a dia.

Vamos pegar como exemplo o nosso objeto ContaBancaria:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package br.com.jugms.weldse.model;
 
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Named;
 
import br.com.jugms.weldse.intercept.Seguro;
 
@ApplicationScoped
@Seguro
public class ContaBancaria {
	//o código já foi visto antes
}


Já vimos este código e o corpo da classe não tem relação com o que vamos ver agora. Agora o mais importante é observarmos as anotações. Temos duas, mas poderíamos ter mais. Para deixar isso mais limpo e com mais significado no meu negócio, poderia criar um estereótipo próprio como o seguinte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package br.com.jugms.weldse.model;
 
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
 
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Stereotype;
 
import br.com.jugms.weldse.intercept.Seguro;
 
@ApplicationScoped
@Seguro
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface JavaneirosBean {
}


E depois mudar nosso ContaBancaria deixando ele assim:

1
2
3
4
5
6
7
8
9
10
package br.com.jugms.weldse.model;
 
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Named;
 
@JavaneirosBean
public class ContaBancaria {
	//o código já foi visto antes
}


Com isso o resultado será o mesmo de antes. Nosso objeto ContaBancaria é @Seguro e @ApplicationScoped. Além disso se depois quisermos dizer que nosso @JavaneirosBean é também um @Alternative ou qualquer outro estereótipo pré-existente ou mesmo um outro estereótipo customizado, basta anotar nossa anotação @JavaneirosBean com a anotação desejada.

Pode parecer estranho usarmos anotações de anotações, mas para exemplificar, se a JPA suportasse isso eu poderia ter uma anotação @Entidade que seria uma @Entity (JPA) e ao mesmo tempo @Named (CDI) e assim poder utilizá-la diretamente nas minhas view JSF com uma única anotação.


Conceitos gerais


Eu disse que ao final do exemplo iria entrar mais na parte teórica de como a CDI trata mais extamente a injeção de dependência, seleção de candidatos etc. Porém por questão de organização, vou deixar isso em um post separado.

3 thoughts on “Desenvolvendo uma aplicação Desktop com Weld – Final

  1. Pingback: Gilliard Cordeiro » Apresentacao sobre CDI (JSR-299) no Javaneiros2009

  2. Boa Tarde Giliard!

    Parabéns novamente pelo Blog!

    Eu estava tentando criar um Estereótipos próprios, usando o exemplo do @JavaneirosBean, mas diferente, eu uso como @SessionScoped.

    Voce sabe como eu posso fazer isso?
    Não criou na session, será um bug?

  3. @Léo
    Obrigado. Sobre o problema, apesar de parecer bug fui ver na spec se havia alguma restrição e não encontrei nenhuma. Assim que eu conseguir um tempinho pra testar isso eu posto o resultado aqui.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>