CDI - Contexts and Dependency Injection
JSR-299
eduardocl@gmail.com
Conteúdo
● Conceitos
○ Bean Types
○ Qualifiers
○ Scopes
○ Bean EL Names
○ Alternatives
○ Stereotypes
Bean
O que é um bean?
Qualquer classe java. No container JEE bean é um componente (classe) cujo ciclo de vida é
gerenciado pelo próprio container de acordo com o escopo (Scopes) ao qual ele pertence. No
container JEE um bean pode conter metadados sobre seu ciclo de vida e interação com outros
componentes.
Um bean possui os seguintes atributos:
● Conjunto de tipos não vazio
● Conjunto de qualificadores não vazio.
● Um escopo
● Um nome EL (Expression Language) - opcional
● Um conjunto interceptors bindings
● Uma implementação do bean
● Pode ser ou não um "alternative" (@Alternative)
Tipos de um Bean
O tipo do bean ou tipos, pois ele pode ter mais de um, são aqueles visíveis para clientes
(client-view)
O tipo do bean pode ser restrito pela anotação @Typed
@Typed(Shop.class)
public class BookShop
extends Business
implements Shop<Book> {
...
}
O bean acima terá apenas dois tipos: Shop e Object e a linha seguinte causará exceção (runtime):
@Inject Shop shop;
BookShop book = (BookShop) shop;
Tipo do bean é o
conjunto de tipos
visto pelo cliente!!
Qualificadores
Podemos ter vários beans que implementam um mesmo tipo de bean. Se um bean implementa a
interface ClientAutrorizer como o cliente poderia utilizar um bean sem que o cliente fique
fortemente acoplado com a implementação da interface ?
Usa-se o qualificador que nada mais é que uma semântica associada ao tipo do bean que
implementa a interface (tipo de bean)
@LDAP
LDAPAuthorizer implements
ClientAuthorizer {}
@OAuth
OAuthAuthorizer
implements ClientAutorizer {}
@Inject @OAuth ClientAuthorizer authorizer;
@Qualifier
@Retention(RUNTIME)
@Target({METHOD,FIELD,PARAMETER,TYPE})
public @interface OAuth {
}
//assim que se declara um qualificador
Um bean pode ter múltiplos
qualificadores
É possível injetar beans usando
qualificadores tb em contrutores e
métodos
Qualificadoes
o CDI fornece os seguintes qualificadores encontrados no pacote
javax.enterprise.inject:
● @Default - todo bean tem esse qualificador
● @Any - todo bean é @Any mesmo não explicitando qualificadores com exceção dos @New.
● @Named - qualificador usado para dar nome a um bean para ser usado na EL
● @New - .....nao sei
@Named("euSouUmBean")
public MyBean {
}
O bean acima possui os seguintes qualificadores: @Any, @Default, @Named
Escopo
Define o ciclo de vida e a visibilidade de um bean. Nem todos tem escopo definido como os
singletons que existem para toda aplicação. Objetos sem estado (stateless), servlets, e stateless
session beans não tem estado da perspectiva do cliente. Vc não sabe em que estado está um servlet
por exemplo. O escopo está sempre associado a um objeto context e serve para criar e destruir o
bean na hora certa e gerenciar seu ciclo de vida de forma transparente para o cliente. O escopo tb
define quais instâncias de um bean estão disponíveis para outras instâncias de outros beans.
O container JEE oferece os seguintes escopos por padrão:
@RequestScoped - servlet. O bean existe somente durante um request http.
@ApplicationScoped
@SessionScoped
@ConversationScoped
@Dependent: pseudo-escopo para objetos dependentes
Escopo
Declarando o escopo do bean:
O escopo de um bean é definido anotando-se a classe do bean, o método produtor (método anotado
com @Produces, responsável por fornecer a instância do bean para o container), campo com o tipo
do escopo.
@SessionScoped
public class User {
@Inject @ApplicaticationScoped Logger logger;
@Produces @SessionScoped User getCurrentUser() { ... }
}
Escopo
O escopo Default:
● Quando o bean não apresenta um escopo explícito em seus estereótipo, então seu escopo é
@Dependent
● Se todos os estereótipos de um bean que declaram um default scope tem o mesmo default
scope então o escopo do bean será default scope
● Se dois estereótipos de um bean declaram cada um o seu escopo e são diferentes, então no
bean deverá ser declarado qual o escopo do bean explicitamente, senão o container dará um
erro de definição.
Se o bean declara um escopo qualquer escopo default que venha a existir nos seus estereótipos será
ignorado.
Escopo
Scope Annotation Duration
Request @RequestScoped A user’s interaction with a web application in a single HTTP
request.
Session @SessionScoped A user’s interaction with a web application across multiple
HTTP requests.
Application @ApplicationScoped Shared state across all users’ interactions with a web
application.
Dependent @Dependent The default scope if none is specified; it means that an object
exists to serve exactly one client (bean) and has the same
lifecycle as that client (bean).
Conversation @ConversationScoped A user’s interaction with a JavaServer Faces application,
within explicit developer-controlled boundaries that extend
the scope across multiple invocations of the JavaServer
Faces lifecycle. All long-running conversations are scoped to
a particular HTTP servlet session and may not cross session
boundaries.
Bean EL Names
Um bean pode ter um nome EL (Expression Language name) e pode ser referenciado através desse
nome.
EL name geralmente são nomes separados por pontos "com.mydomain.myapp.beanName"
OBS: Não existe nenhuma relação entre o EL name, o session bean name e o EJB name do bean.
No jsp podemos acessar um bean pelo EL name:
<h: outputText value="#{products.total}"/>
A anotação @Named("currentOrder") permite dar um nome ao bean (anotação de classe)
@Named("currentOrder")
public class Order { .... }
Bean EL Names
Default EL Names:
Em algumas circustâncias o container deverá associar um nome EL default (default EL Name):
● Uma classe bean ou método producer (com a anotação @Producer) declara a anotação @Named sem
um nome específico.
● Quando o bean declara estereótipos que declaram uma anotação @Named vazia, sem especificar
nenhum nome.
Geralmente o nome do bean será o "unqualified class name" ex: ProductList -> productList
Managed Beans, Session Beans -> unqualified class name
Producer methods: nome do método suprimido o "get" e "set"
@Produces @Named
public List<Products> getProducts(){} -> o nome desse método será "products"
Producer fields:
@Named List<product> products = .... -> o nome será o próprio nome do campo: "products"
Alternatives
É um bean que deve declarado explicitamente no arquivo beans.xml para disponível para injeção e
lookup por EL name.
Podem ser declarados pela anotação @Alternative na classe, producer method ou campo.
@Alternative
public class MockOrder implements Order { ... }
META-INF ou WEB-INF/
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<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://jboss.org/schema/cdi/beans_1_0.xsd
http://jboss.org/schema/weld/beans
http://jboss.org/schema/weld/beans_1_1.xsd">
<alternatives>
<class>com.mydomain.myapp.test.MockOrder</class>
<alternatives>
</beans>
Estereótipos - Stereotypes
Em alguns sistemas padrões de projeto são utilizados e determinados objetos realizam um
determinado papel como "controller", "view", "model", "dao". Eles realizam uma determinada
operação de acordo com o papel dentro do patter, framework ou arquitetura. Uma Dao, por
exemplo, é responsável pela persistência dos dados.
Um estereótipo (stereotype) permite o desenvolvedor identificar o papel de uma classe e declarar
alugns metadados para os beans que fazem parte desse papel.
Um estereótipo encapsula:
● um escopo default
● conjunto de interceptadores (interceptors binding)
pode especificar:
● que todos os beans com o estereótipos tenham EL names default
● que todos os beans com o estereótipo sejam alternatives
Estereótipos - Stereotypes
Um bean pode ter mais de um estereótipo. O estereótipo é definido como uma anotação:
@Target({TYPE, METHOD, FIELD}) ou
@Target(TYPE) ou
@Target(METHOD) ou
@Target(FIELD) ou
@Target({METHOD,FIELD}) AND
@Retention(RUNTIME)
@Alternative
@RequestScope
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface MockAction(){}
0 ResquestScope será o escopo default desse do estereótipo Action.Além disso todos os beans
desse estereótipo serão alternativas.
Estereótipos - Stereotypes
Algumas considerações:
O estereótipo não deve ser anotado @Typed
O estereótipo pode declarar outros estereótipos
As declarações em estereótipos são transitivas
O estereótipo pode declarar @Alternative, especificando que cada bean será uma alternativa
Estereótipos fornecidos pelo container:
@Model - beans da camada model de uma aplicação MVC.
@Interceptor - visto nos próximos slides
@Decorator - visto nos próximos slides
Modelo de Programação
● Managed Beans
● Session Beans
● Producer Methods
● Producer Fields
● Resources (Java EE resources, persistence contexts, persistence units,
remote EJBs and web services)
Modelo de Programação
Managed Beans
Managed bean é um bean implementaado por uma classe java, não podendo ser anotado por ambas:
@Interceptor E @Decorator (gera erro de definição)
Classes que são managed beans:
* não é classe interna estática
* classe concreta, ou anotada @Decorator
* não anotada como componente EJB ou declarada como uma classe EJB em ejb-jar.xml
* Não implementa javax.enterprise.inject.spi.Extension
* Possui construtor:
- default: sem parâmetros ou
- não possui construtor default mas tem um construtor anotado com @Inject
-> Todas as classes que atendam esses requisitos são managed beans sem precisar de nenhuma
definição especial.
Modelo de Programação
Session Beans
É um bean que implementa o tipo "session bean" de acordo com a especificação EJB, que define a
semântica e o ciclo de vida dos session beans. Esses beans não podem ser anotados como
@Interceptor e @Decorator.
Declaração:
@Singleton @Stateless
class Shop{...} @Mock
@Named("loginAction")
public MockLoginAct implements Action
@Stateless
class PaymentProcessorImpl implement PaymentProcessor {....}
Modelo de Programação
Producer Methods
Métodos produtores é o fornecedor de objetos que serão injetados pelo container, onde:
* os objetos a serem injetados não são necessariamente instâncias de beans
* tipo concreto dos objetos vai varia em tempo de execução
* os objetos necessitam de inicialização customizada que não pode ser realizada pelo
construtor da classe.
Um producer method deve ser:
* não-abstrato, pode ser membro de um bean ou session bean. Pode ser não-estático
ou estático
* se for parte de um session bean ele deve ser estático um método de negócio do EJB.
Modelo de Programação
Producers Methods:
Tipos:
* Os tipo de retorno pode ser uma interface, ou seja, uma infinidade de tipos que
implementam a interface direta ou indiretamente mais java.lang.Object
* pode ser uma primitiva ou array contendo exatamente dois tipos: o tipo de retorno e
java.lang.object
* se o tipo de retorno é uma classe o tipo de retorno engloba as superclasses e interfaces
que ela implementa direta ou indiretamente.
@Produces PaymentProcessor getPaymentProcessor(){...}
@Produces @ApplicationScoped @Catalog @Named("catalog")
List<Product> getProducts() {...}
Modelo de Programação
Producer Fields
É uma alternativa simples ao producer method. É um campo de um bean que pode ser estático ou
não. Se for parte de um session bean ele deve ser estático. Se em algum momento ele assumir o
valor null ele deve ter o escopo @Dependent senão ocorrerá uma IllegalProductException
Os tipos de um producer field são os mesmos de um producer method.
public class Shop {
@Produces PaymentProcessor paymentProcessor = ...;
@Produces List<Produces> products = ...;
}
Um producer field não deve ter a anotação @Inject senão ocorrerá erro de definição.
Modelo de Programação
Resources
Resource é um bean que representa um referência a um recurso como um persistence context,
persistent unit, EJB remoto, web service no ambiente de componentes JEE.
@Produces @WebServiceRef(lookup="java:app/service/PaymentService")
PaymentService service;
@Produces @EJB(ejbLink="../their.jar#PaymentService")
PaymentService service;
@Produces @Resource(lookup="java:global/env/jdbc/CustomerDatabase")
@CustumerDatabase Database customerDatabase;
@Produces @PersistenceContext(unitName="CustomerDatabase")
@CustomerDatabase EntityManager customerDatabasePersistenceContext;
@Produces @PersistenceUnit(unitName="CustomerDatabase")
@CustomerDatabase EntityManagerFactory customerDatabasePersistenceUnit;
Modelo de Programação
Initializer Methods
É um método não-abstrato, não-estático, não-genérico de uma classe bean, ou de qualquer componente JEE que
suporte injeção. Se o bean é um session bean, o initializer method não precisa ser um método de negócio.
Um bean pode ter zero ou vários initalizer methods.
Métodos interceptadores nunca são chamados qdo o container chamar um initializer method.
A aplicação pode chamar initliazer methods diretamente mas nenhum parâmetro será passado pelo container.
@ConversationScoped
public class Order {
private Product product;
private Product product;
@Inject setProduct(@Selected Product product){ ... }
@Inject setCustomer(User customer) { ... }
}
Modelo de Programação
@New Beans
@New é um qualificador (qualifier). Para cada bean ou session bean existe um segundo bean que:
* tem a mesma classe bean
* tem os mesmos tipos de bean
* tem o mesmo construtor, initializer methods e injected fields
* tem os mesmo interceptors bindings
Mas:
* tem escopo @Dependent
* tem exatamente um qualificador @javax.enterprise.inject.New(Order.class)
* não tem EL name
* não tem estereótipos
* não é uma alternativa
* está habilitado se e somente se algum outro bean habilitado tem um injection point com a
o qualificador @New(X.class)
Modelo de Programação
Quando um bean está habilitado?
Quando:
* está publicado (deployed) em um bean arquive (pacote contendo o arquivo beans.xml)
* Não producer method ou producer field de um bean desabilitado
* Não é especializado por nenhum outro bean habilitado. (@Specializes ver especificação)
* Não é uma alternativa ou é uma alternativa selecionada de pelo menos um bean archive -
seja lá o que isso quer dizer.....
Interceptors
Definição:
São objetos que executam regras que ocorrem em todas as camada (cross-cutting concerns), como
logging, transação, checagem de segurança, etc. Não estão associadas a um objeto do domínio do
negócio, como nos decoradores. Os interceptadores podem ser associados ao beans através de um
mecanismo denominado interceptor bindings.
Declarando um interceptor bind:
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD}) //ou @Target(TYPE)
@Retention(RUNTIME)
public @interface Transacional { }
Os intercepadotes podem ter valores membros:
@Transactional(requireLog="true")
Interceptors
Implementando o interceptador
Uma vez definido o interceptor binding, vamos implementar a classe que será o interceptor:
@Transactional //nome do interceptor binding
@Interceptor
public class TransactionalInterceptor {
@AroundInvoke
public Object manageTransaction(InvocationContext ctx) throws Exception {
return ctx.proceed();
}
}
Anota-se o bean (classe ou método). Se a anotação for na classe todos os métodos serão interceptados.
@Transactional @Transactional
public class Dao { ... } public void insert(Bean b) {....}
Interceptors
Por último, devemos habilitar os interceptadores uma vez que por default eles estão desabilitados.
Isso é feito no arquivo beans.xml:
<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>org.mycompany.myfwk.TransactionInterceptor</class>
<class>org.mycompany.myfwk.LoggingInterceptor</class>
</interceptors>
</beans>
Os interceptadores serão executados na ordem que aparecem nesse arquivo.
Decorators
Decorators (desing pattern) implementa um ou mais tipos de bean e intercepta invocações de
método de negócio dos beans que implementam esses tipos de beans. A esses beans dá-se o nome
de beans decorados (decorated beans).
São similares aos interceptadores, mas como eles implementam diretamente operações de negócio,
eles não são capazes e nem se servem para implementar regras que permeiam todas as camadas do
projeto (cross-cutting concerns), como os iterceptadores.
Os decoradores podem estar associados com qualquer managed bean que não seja ele mesmo um
decorador, um interceptador ou EJB session bean. E a classe d decorador e suas superclasses não são
tipos decorados pelo decorador.
A instância do decorator é dependente da instância do objeto que ele decora.
Decorator
Declarando um decorador
Usa-se o estereótipo @javax.decorator.Decorator
@Decorator
class TimestampLogger implements Logger { .... }
Todo decorador tem um delegate injection point : bean da classe decorada. E deve ter somente um
delegate injection point.
@Decorator
class TimestpLogger implements Logger {
@Inject @Delegate @Any Logger logger;
ou:
@Inject public TimestpLogger( @Delegate @Debug Logger logger)
{this.logger = logger}
}
Decorator
Decoradores por default não são habilitados. Deve-se ir ao aquivo beans.xml e colocar a classe do
decorador:
<?xml version="1.0"?>
<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">
<decorators>
<class>com.ecl.trainning.cdi.decorator.OrderDecorator</class>
<class>com.ecl.trainning.cdi.decorator.AnotherOrderDecorator</class>
</decorators>
</beans>
A ordem das classes é a ordem que eles serão executados.
Decorator
Exemplo completo
@Decorator
public abstract class OrderDecorator implements Order {
@Inject @Delegate @MyOrder //delegate injection point
private Order order;
public OrderDecorator() {
}
@Override
public String getNumber() {
logger.info("calling getNumber from decorator");
return order.getNumber();
}
}
Events
Beans podem consumir e disparar eventos. Isso torna possível desacoplar os beans completamente,
sem necessidade de nenhuma dependência em tempo de compilação. Os eventos permitem dou ou
mais bean stateful em camadas diferem da arquitetura (tier) sincronizem seus estados a medida que
mudanças em seus estados ocorrem.
Os eventos são tratados por objetos que observam esses eventos.
O evento é:
* um objeto java: event
* um conjunto vazio ou não de várias instâncias de qualificadores - event qualifiers - que
permite os observadores diferenciarem o tipo dos eventos
@Qualifier
@Retention({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Updated {}
Events
Observando eventos: métodos que utilizam @Observes
public void onAnyDocumentEvent( @Observes Document document)
//observando um evento com um qualificador
//o método pode ter parâmetros adicionais
public void afterUpdating( @Observes @Updated @ByAdmin Document document,
User user)
Produtores de eventos:
Os objetos que disparam eventos utilizam a interface parametrizada Event para disparar um evento.
A instância da interface é injetada da seguinte maneira:
@Inject @Any Event<Document> documentEvent;
o produtor dispara o evento passando o objeto do evento:
documentEvent.fire(document)
Events
Eventos podem ter valores:
@Qualifier
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Role {
String value();
}
//disparando o evento
public void login() {
final User user = ...;
loggedInEvent.fire( new LoggedInEvent(user),
new RoleQualifier() { public String value() { return
user.getRole(); } );
}
public abstract class RoleQualifier
extends AnnotationLiteral<Role>
implements Role {}
public void afterLogin(@Observes LoggedInEvent event) { ... }
public void afterAdminLogin(@Observes @Role("admin") LoggedInEvent event)
{}
Events
Observadores Condicionais: são métodos que são notificados de um evento somente se a instância
do bean que define o método observer já existir no contexto atual.
public void refreshOnDocumentUpdate(@Observes( receive=IF_EXISTS) @Updated
Document d){}
Bean que seja @Dependent e tenha um método observador com uma condicional ocasionará um erro
de definição que será detectado pelo container.
Métodos Observadores Transacionais: são métodos que recebem notificações antes, durante ou
depois de uma transação na qual o evento foi disparado. Se nenhuma transação está em andamento
qdo o evento é disparado esses métodos são notificados ao mesmo tempo que os outros
obsercadores. As notificações ocorrem:
* before completion
* after completion
* after success
* after failure
void onDocumentUpdate(@Observes (during=AFTER_SUCCESS) @Updated Document
doc)
public enum TransactionPhase {
IN_PROGRESS,
BEFORE_COMPLETION,
AFTER_COMPLETION,
AFTER_FAILURE,
AFTER_SUCCESS
}

Conceitos de CDI - Contextos e Injeção de Dependências

  • 1.
    CDI - Contextsand Dependency Injection JSR-299 eduardocl@gmail.com
  • 2.
    Conteúdo ● Conceitos ○ BeanTypes ○ Qualifiers ○ Scopes ○ Bean EL Names ○ Alternatives ○ Stereotypes
  • 3.
    Bean O que éum bean? Qualquer classe java. No container JEE bean é um componente (classe) cujo ciclo de vida é gerenciado pelo próprio container de acordo com o escopo (Scopes) ao qual ele pertence. No container JEE um bean pode conter metadados sobre seu ciclo de vida e interação com outros componentes. Um bean possui os seguintes atributos: ● Conjunto de tipos não vazio ● Conjunto de qualificadores não vazio. ● Um escopo ● Um nome EL (Expression Language) - opcional ● Um conjunto interceptors bindings ● Uma implementação do bean ● Pode ser ou não um "alternative" (@Alternative)
  • 4.
    Tipos de umBean O tipo do bean ou tipos, pois ele pode ter mais de um, são aqueles visíveis para clientes (client-view) O tipo do bean pode ser restrito pela anotação @Typed @Typed(Shop.class) public class BookShop extends Business implements Shop<Book> { ... } O bean acima terá apenas dois tipos: Shop e Object e a linha seguinte causará exceção (runtime): @Inject Shop shop; BookShop book = (BookShop) shop; Tipo do bean é o conjunto de tipos visto pelo cliente!!
  • 5.
    Qualificadores Podemos ter váriosbeans que implementam um mesmo tipo de bean. Se um bean implementa a interface ClientAutrorizer como o cliente poderia utilizar um bean sem que o cliente fique fortemente acoplado com a implementação da interface ? Usa-se o qualificador que nada mais é que uma semântica associada ao tipo do bean que implementa a interface (tipo de bean) @LDAP LDAPAuthorizer implements ClientAuthorizer {} @OAuth OAuthAuthorizer implements ClientAutorizer {} @Inject @OAuth ClientAuthorizer authorizer; @Qualifier @Retention(RUNTIME) @Target({METHOD,FIELD,PARAMETER,TYPE}) public @interface OAuth { } //assim que se declara um qualificador Um bean pode ter múltiplos qualificadores É possível injetar beans usando qualificadores tb em contrutores e métodos
  • 6.
    Qualificadoes o CDI forneceos seguintes qualificadores encontrados no pacote javax.enterprise.inject: ● @Default - todo bean tem esse qualificador ● @Any - todo bean é @Any mesmo não explicitando qualificadores com exceção dos @New. ● @Named - qualificador usado para dar nome a um bean para ser usado na EL ● @New - .....nao sei @Named("euSouUmBean") public MyBean { } O bean acima possui os seguintes qualificadores: @Any, @Default, @Named
  • 7.
    Escopo Define o ciclode vida e a visibilidade de um bean. Nem todos tem escopo definido como os singletons que existem para toda aplicação. Objetos sem estado (stateless), servlets, e stateless session beans não tem estado da perspectiva do cliente. Vc não sabe em que estado está um servlet por exemplo. O escopo está sempre associado a um objeto context e serve para criar e destruir o bean na hora certa e gerenciar seu ciclo de vida de forma transparente para o cliente. O escopo tb define quais instâncias de um bean estão disponíveis para outras instâncias de outros beans. O container JEE oferece os seguintes escopos por padrão: @RequestScoped - servlet. O bean existe somente durante um request http. @ApplicationScoped @SessionScoped @ConversationScoped @Dependent: pseudo-escopo para objetos dependentes
  • 8.
    Escopo Declarando o escopodo bean: O escopo de um bean é definido anotando-se a classe do bean, o método produtor (método anotado com @Produces, responsável por fornecer a instância do bean para o container), campo com o tipo do escopo. @SessionScoped public class User { @Inject @ApplicaticationScoped Logger logger; @Produces @SessionScoped User getCurrentUser() { ... } }
  • 9.
    Escopo O escopo Default: ●Quando o bean não apresenta um escopo explícito em seus estereótipo, então seu escopo é @Dependent ● Se todos os estereótipos de um bean que declaram um default scope tem o mesmo default scope então o escopo do bean será default scope ● Se dois estereótipos de um bean declaram cada um o seu escopo e são diferentes, então no bean deverá ser declarado qual o escopo do bean explicitamente, senão o container dará um erro de definição. Se o bean declara um escopo qualquer escopo default que venha a existir nos seus estereótipos será ignorado.
  • 10.
    Escopo Scope Annotation Duration Request@RequestScoped A user’s interaction with a web application in a single HTTP request. Session @SessionScoped A user’s interaction with a web application across multiple HTTP requests. Application @ApplicationScoped Shared state across all users’ interactions with a web application. Dependent @Dependent The default scope if none is specified; it means that an object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean). Conversation @ConversationScoped A user’s interaction with a JavaServer Faces application, within explicit developer-controlled boundaries that extend the scope across multiple invocations of the JavaServer Faces lifecycle. All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries.
  • 11.
    Bean EL Names Umbean pode ter um nome EL (Expression Language name) e pode ser referenciado através desse nome. EL name geralmente são nomes separados por pontos "com.mydomain.myapp.beanName" OBS: Não existe nenhuma relação entre o EL name, o session bean name e o EJB name do bean. No jsp podemos acessar um bean pelo EL name: <h: outputText value="#{products.total}"/> A anotação @Named("currentOrder") permite dar um nome ao bean (anotação de classe) @Named("currentOrder") public class Order { .... }
  • 12.
    Bean EL Names DefaultEL Names: Em algumas circustâncias o container deverá associar um nome EL default (default EL Name): ● Uma classe bean ou método producer (com a anotação @Producer) declara a anotação @Named sem um nome específico. ● Quando o bean declara estereótipos que declaram uma anotação @Named vazia, sem especificar nenhum nome. Geralmente o nome do bean será o "unqualified class name" ex: ProductList -> productList Managed Beans, Session Beans -> unqualified class name Producer methods: nome do método suprimido o "get" e "set" @Produces @Named public List<Products> getProducts(){} -> o nome desse método será "products" Producer fields: @Named List<product> products = .... -> o nome será o próprio nome do campo: "products"
  • 13.
    Alternatives É um beanque deve declarado explicitamente no arquivo beans.xml para disponível para injeção e lookup por EL name. Podem ser declarados pela anotação @Alternative na classe, producer method ou campo. @Alternative public class MockOrder implements Order { ... } META-INF ou WEB-INF/ beans.xml <?xml version="1.0" encoding="UTF-8"?> <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://jboss.org/schema/cdi/beans_1_0.xsd http://jboss.org/schema/weld/beans http://jboss.org/schema/weld/beans_1_1.xsd"> <alternatives> <class>com.mydomain.myapp.test.MockOrder</class> <alternatives> </beans>
  • 14.
    Estereótipos - Stereotypes Emalguns sistemas padrões de projeto são utilizados e determinados objetos realizam um determinado papel como "controller", "view", "model", "dao". Eles realizam uma determinada operação de acordo com o papel dentro do patter, framework ou arquitetura. Uma Dao, por exemplo, é responsável pela persistência dos dados. Um estereótipo (stereotype) permite o desenvolvedor identificar o papel de uma classe e declarar alugns metadados para os beans que fazem parte desse papel. Um estereótipo encapsula: ● um escopo default ● conjunto de interceptadores (interceptors binding) pode especificar: ● que todos os beans com o estereótipos tenham EL names default ● que todos os beans com o estereótipo sejam alternatives
  • 15.
    Estereótipos - Stereotypes Umbean pode ter mais de um estereótipo. O estereótipo é definido como uma anotação: @Target({TYPE, METHOD, FIELD}) ou @Target(TYPE) ou @Target(METHOD) ou @Target(FIELD) ou @Target({METHOD,FIELD}) AND @Retention(RUNTIME) @Alternative @RequestScope @Stereotype @Target(TYPE) @Retention(RUNTIME) public @interface MockAction(){} 0 ResquestScope será o escopo default desse do estereótipo Action.Além disso todos os beans desse estereótipo serão alternativas.
  • 16.
    Estereótipos - Stereotypes Algumasconsiderações: O estereótipo não deve ser anotado @Typed O estereótipo pode declarar outros estereótipos As declarações em estereótipos são transitivas O estereótipo pode declarar @Alternative, especificando que cada bean será uma alternativa Estereótipos fornecidos pelo container: @Model - beans da camada model de uma aplicação MVC. @Interceptor - visto nos próximos slides @Decorator - visto nos próximos slides
  • 17.
    Modelo de Programação ●Managed Beans ● Session Beans ● Producer Methods ● Producer Fields ● Resources (Java EE resources, persistence contexts, persistence units, remote EJBs and web services)
  • 18.
    Modelo de Programação ManagedBeans Managed bean é um bean implementaado por uma classe java, não podendo ser anotado por ambas: @Interceptor E @Decorator (gera erro de definição) Classes que são managed beans: * não é classe interna estática * classe concreta, ou anotada @Decorator * não anotada como componente EJB ou declarada como uma classe EJB em ejb-jar.xml * Não implementa javax.enterprise.inject.spi.Extension * Possui construtor: - default: sem parâmetros ou - não possui construtor default mas tem um construtor anotado com @Inject -> Todas as classes que atendam esses requisitos são managed beans sem precisar de nenhuma definição especial.
  • 19.
    Modelo de Programação SessionBeans É um bean que implementa o tipo "session bean" de acordo com a especificação EJB, que define a semântica e o ciclo de vida dos session beans. Esses beans não podem ser anotados como @Interceptor e @Decorator. Declaração: @Singleton @Stateless class Shop{...} @Mock @Named("loginAction") public MockLoginAct implements Action @Stateless class PaymentProcessorImpl implement PaymentProcessor {....}
  • 20.
    Modelo de Programação ProducerMethods Métodos produtores é o fornecedor de objetos que serão injetados pelo container, onde: * os objetos a serem injetados não são necessariamente instâncias de beans * tipo concreto dos objetos vai varia em tempo de execução * os objetos necessitam de inicialização customizada que não pode ser realizada pelo construtor da classe. Um producer method deve ser: * não-abstrato, pode ser membro de um bean ou session bean. Pode ser não-estático ou estático * se for parte de um session bean ele deve ser estático um método de negócio do EJB.
  • 21.
    Modelo de Programação ProducersMethods: Tipos: * Os tipo de retorno pode ser uma interface, ou seja, uma infinidade de tipos que implementam a interface direta ou indiretamente mais java.lang.Object * pode ser uma primitiva ou array contendo exatamente dois tipos: o tipo de retorno e java.lang.object * se o tipo de retorno é uma classe o tipo de retorno engloba as superclasses e interfaces que ela implementa direta ou indiretamente. @Produces PaymentProcessor getPaymentProcessor(){...} @Produces @ApplicationScoped @Catalog @Named("catalog") List<Product> getProducts() {...}
  • 22.
    Modelo de Programação ProducerFields É uma alternativa simples ao producer method. É um campo de um bean que pode ser estático ou não. Se for parte de um session bean ele deve ser estático. Se em algum momento ele assumir o valor null ele deve ter o escopo @Dependent senão ocorrerá uma IllegalProductException Os tipos de um producer field são os mesmos de um producer method. public class Shop { @Produces PaymentProcessor paymentProcessor = ...; @Produces List<Produces> products = ...; } Um producer field não deve ter a anotação @Inject senão ocorrerá erro de definição.
  • 23.
    Modelo de Programação Resources Resourceé um bean que representa um referência a um recurso como um persistence context, persistent unit, EJB remoto, web service no ambiente de componentes JEE. @Produces @WebServiceRef(lookup="java:app/service/PaymentService") PaymentService service; @Produces @EJB(ejbLink="../their.jar#PaymentService") PaymentService service; @Produces @Resource(lookup="java:global/env/jdbc/CustomerDatabase") @CustumerDatabase Database customerDatabase; @Produces @PersistenceContext(unitName="CustomerDatabase") @CustomerDatabase EntityManager customerDatabasePersistenceContext; @Produces @PersistenceUnit(unitName="CustomerDatabase") @CustomerDatabase EntityManagerFactory customerDatabasePersistenceUnit;
  • 24.
    Modelo de Programação InitializerMethods É um método não-abstrato, não-estático, não-genérico de uma classe bean, ou de qualquer componente JEE que suporte injeção. Se o bean é um session bean, o initializer method não precisa ser um método de negócio. Um bean pode ter zero ou vários initalizer methods. Métodos interceptadores nunca são chamados qdo o container chamar um initializer method. A aplicação pode chamar initliazer methods diretamente mas nenhum parâmetro será passado pelo container. @ConversationScoped public class Order { private Product product; private Product product; @Inject setProduct(@Selected Product product){ ... } @Inject setCustomer(User customer) { ... } }
  • 25.
    Modelo de Programação @NewBeans @New é um qualificador (qualifier). Para cada bean ou session bean existe um segundo bean que: * tem a mesma classe bean * tem os mesmos tipos de bean * tem o mesmo construtor, initializer methods e injected fields * tem os mesmo interceptors bindings Mas: * tem escopo @Dependent * tem exatamente um qualificador @javax.enterprise.inject.New(Order.class) * não tem EL name * não tem estereótipos * não é uma alternativa * está habilitado se e somente se algum outro bean habilitado tem um injection point com a o qualificador @New(X.class)
  • 26.
    Modelo de Programação Quandoum bean está habilitado? Quando: * está publicado (deployed) em um bean arquive (pacote contendo o arquivo beans.xml) * Não producer method ou producer field de um bean desabilitado * Não é especializado por nenhum outro bean habilitado. (@Specializes ver especificação) * Não é uma alternativa ou é uma alternativa selecionada de pelo menos um bean archive - seja lá o que isso quer dizer.....
  • 27.
    Interceptors Definição: São objetos queexecutam regras que ocorrem em todas as camada (cross-cutting concerns), como logging, transação, checagem de segurança, etc. Não estão associadas a um objeto do domínio do negócio, como nos decoradores. Os interceptadores podem ser associados ao beans através de um mecanismo denominado interceptor bindings. Declarando um interceptor bind: @Inherited @InterceptorBinding @Target({TYPE, METHOD}) //ou @Target(TYPE) @Retention(RUNTIME) public @interface Transacional { } Os intercepadotes podem ter valores membros: @Transactional(requireLog="true")
  • 28.
    Interceptors Implementando o interceptador Umavez definido o interceptor binding, vamos implementar a classe que será o interceptor: @Transactional //nome do interceptor binding @Interceptor public class TransactionalInterceptor { @AroundInvoke public Object manageTransaction(InvocationContext ctx) throws Exception { return ctx.proceed(); } } Anota-se o bean (classe ou método). Se a anotação for na classe todos os métodos serão interceptados. @Transactional @Transactional public class Dao { ... } public void insert(Bean b) {....}
  • 29.
    Interceptors Por último, devemoshabilitar os interceptadores uma vez que por default eles estão desabilitados. Isso é feito no arquivo beans.xml: <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>org.mycompany.myfwk.TransactionInterceptor</class> <class>org.mycompany.myfwk.LoggingInterceptor</class> </interceptors> </beans> Os interceptadores serão executados na ordem que aparecem nesse arquivo.
  • 30.
    Decorators Decorators (desing pattern)implementa um ou mais tipos de bean e intercepta invocações de método de negócio dos beans que implementam esses tipos de beans. A esses beans dá-se o nome de beans decorados (decorated beans). São similares aos interceptadores, mas como eles implementam diretamente operações de negócio, eles não são capazes e nem se servem para implementar regras que permeiam todas as camadas do projeto (cross-cutting concerns), como os iterceptadores. Os decoradores podem estar associados com qualquer managed bean que não seja ele mesmo um decorador, um interceptador ou EJB session bean. E a classe d decorador e suas superclasses não são tipos decorados pelo decorador. A instância do decorator é dependente da instância do objeto que ele decora.
  • 31.
    Decorator Declarando um decorador Usa-seo estereótipo @javax.decorator.Decorator @Decorator class TimestampLogger implements Logger { .... } Todo decorador tem um delegate injection point : bean da classe decorada. E deve ter somente um delegate injection point. @Decorator class TimestpLogger implements Logger { @Inject @Delegate @Any Logger logger; ou: @Inject public TimestpLogger( @Delegate @Debug Logger logger) {this.logger = logger} }
  • 32.
    Decorator Decoradores por defaultnão são habilitados. Deve-se ir ao aquivo beans.xml e colocar a classe do decorador: <?xml version="1.0"?> <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"> <decorators> <class>com.ecl.trainning.cdi.decorator.OrderDecorator</class> <class>com.ecl.trainning.cdi.decorator.AnotherOrderDecorator</class> </decorators> </beans> A ordem das classes é a ordem que eles serão executados.
  • 33.
    Decorator Exemplo completo @Decorator public abstractclass OrderDecorator implements Order { @Inject @Delegate @MyOrder //delegate injection point private Order order; public OrderDecorator() { } @Override public String getNumber() { logger.info("calling getNumber from decorator"); return order.getNumber(); } }
  • 34.
    Events Beans podem consumire disparar eventos. Isso torna possível desacoplar os beans completamente, sem necessidade de nenhuma dependência em tempo de compilação. Os eventos permitem dou ou mais bean stateful em camadas diferem da arquitetura (tier) sincronizem seus estados a medida que mudanças em seus estados ocorrem. Os eventos são tratados por objetos que observam esses eventos. O evento é: * um objeto java: event * um conjunto vazio ou não de várias instâncias de qualificadores - event qualifiers - que permite os observadores diferenciarem o tipo dos eventos @Qualifier @Retention({FIELD, PARAMETER}) @Retention(RUNTIME) public @interface Updated {}
  • 35.
    Events Observando eventos: métodosque utilizam @Observes public void onAnyDocumentEvent( @Observes Document document) //observando um evento com um qualificador //o método pode ter parâmetros adicionais public void afterUpdating( @Observes @Updated @ByAdmin Document document, User user) Produtores de eventos: Os objetos que disparam eventos utilizam a interface parametrizada Event para disparar um evento. A instância da interface é injetada da seguinte maneira: @Inject @Any Event<Document> documentEvent; o produtor dispara o evento passando o objeto do evento: documentEvent.fire(document)
  • 36.
    Events Eventos podem tervalores: @Qualifier @Target(PARAMETER) @Retention(RUNTIME) public @interface Role { String value(); } //disparando o evento public void login() { final User user = ...; loggedInEvent.fire( new LoggedInEvent(user), new RoleQualifier() { public String value() { return user.getRole(); } ); } public abstract class RoleQualifier extends AnnotationLiteral<Role> implements Role {} public void afterLogin(@Observes LoggedInEvent event) { ... } public void afterAdminLogin(@Observes @Role("admin") LoggedInEvent event) {}
  • 37.
    Events Observadores Condicionais: sãométodos que são notificados de um evento somente se a instância do bean que define o método observer já existir no contexto atual. public void refreshOnDocumentUpdate(@Observes( receive=IF_EXISTS) @Updated Document d){} Bean que seja @Dependent e tenha um método observador com uma condicional ocasionará um erro de definição que será detectado pelo container. Métodos Observadores Transacionais: são métodos que recebem notificações antes, durante ou depois de uma transação na qual o evento foi disparado. Se nenhuma transação está em andamento qdo o evento é disparado esses métodos são notificados ao mesmo tempo que os outros obsercadores. As notificações ocorrem: * before completion * after completion * after success * after failure void onDocumentUpdate(@Observes (during=AFTER_SUCCESS) @Updated Document doc) public enum TransactionPhase { IN_PROGRESS, BEFORE_COMPLETION, AFTER_COMPLETION, AFTER_FAILURE, AFTER_SUCCESS }