37
CDI - Contexts and Dependency Injection JSR-299 [email protected]

Cdi conceitos

Embed Size (px)

DESCRIPTION

Resumos dos conceitos de CDI.

Citation preview

Page 1: Cdi conceitos

CDI - Contexts and Dependency Injection [email protected]

Page 2: Cdi conceitos

Conteúdo

● Conceitos○ Bean Types○ Qualifiers○ Scopes○ Bean EL Names○ Alternatives○ Stereotypes

Page 3: Cdi conceitos

BeanO 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)

Page 4: Cdi conceitos

Tipos de um BeanO 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!!

Page 5: Cdi conceitos

QualificadoresPodemos 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)

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

Page 6: Cdi conceitos

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

Page 7: Cdi conceitos

EscopoDefine 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

Page 8: Cdi conceitos

EscopoDeclarando 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.

@SessionScopedpublic class User {

@Inject @ApplicaticationScoped Logger logger;

@Produces @SessionScoped User getCurrentUser() { ... }

}

Page 9: Cdi conceitos

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.

Page 10: Cdi conceitos

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.

Page 11: Cdi conceitos

Bean EL NamesUm 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 { .... }

Page 12: Cdi conceitos

Bean EL NamesDefault 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 -> productListManaged Beans, Session Beans -> unqualified class nameProducer 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"

Page 13: Cdi conceitos

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>

Page 14: Cdi conceitos

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

Page 15: Cdi conceitos

Estereótipos - StereotypesUm 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.

Page 16: Cdi conceitos

Estereótipos - StereotypesAlgumas considerações:

O estereótipo não deve ser anotado @TypedO estereótipo pode declarar outros estereótiposAs declarações em estereótipos são transitivasO 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

Page 17: Cdi conceitos

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)

Page 18: Cdi conceitos

Modelo de ProgramaçãoManaged BeansManaged 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.

Page 19: Cdi conceitos

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 {....}

Page 20: Cdi conceitos

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.

Page 21: Cdi conceitos

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() {...}

Page 22: Cdi conceitos

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.

Page 23: Cdi conceitos

Modelo de ProgramaçãoResourcesResource é 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;

Page 24: Cdi conceitos

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) { ... }

}

Page 25: Cdi conceitos

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)

Page 26: Cdi conceitos

Modelo de ProgramaçãoQuando 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.....

Page 27: Cdi conceitos

InterceptorsDefiniçã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")

Page 28: Cdi conceitos

InterceptorsImplementando 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) {....}

Page 29: Cdi conceitos

InterceptorsPor ú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.

Page 30: Cdi conceitos

DecoratorsDecorators (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.

Page 31: Cdi conceitos

DecoratorDeclarando 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}

}

Page 32: Cdi conceitos

DecoratorDecoradores 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.

Page 33: Cdi conceitos

DecoratorExemplo 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();

}

}

Page 34: Cdi conceitos

EventsBeans 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 {}

Page 35: Cdi conceitos

EventsObservando 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)

Page 36: Cdi conceitos

EventsEventos 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) {}

Page 37: Cdi conceitos

EventsObservadores 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

}