Upload
elvis-rocha
View
1.621
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Java EE 6 tópicos avançados
Citation preview
Java EE 6
Elvis Henrique RochaEspecialista [email protected]
JavaEE 6
Tópicos:• JavaEE 6 Overview
• Java Persistence 2.0
• Enterprise JavaBeans 3.1
• Contexts and Dependency Injection for Java 1.0
JavaEE 6 Overview
• Desenvolvimento Simplificado (+ Annotations, + POJO)
• Perfis: (Web Profile e Full Profile)
• Novidades:
JAX-RS
Managed Beans
CDI
Bean Validation
EJB 3.1 (Interceptors 1.1)
Container Architecture
Tiers
Profiles
Java Persistence API 2.0
• Arquitetura do Hibernate:
Hibernate / JPA Entity (EJB 3) Regras:–
Classes anotadas com @Entity e com pelo menos um @Id definido
Classes devem seguir a conven o JavaBeansçã
Classes, métodos ou variáveis n o podem usar ã final
Deve ter um constructor sem argumentos (public ou protected)
Collections devem ser interfaces (n o podem ser implementa es)ã çõ
Classes de alto nível (n o pode ser classe interna ou aninhada)ã
Um Enum ou uma Interface n o podem ser classes persistentesã
Classes abstratas e concretas podem ser persistentes
Usar serializable para objetos detachados
Sem interface para implementar ou classes para extender
Sem programa o intrusiva nas classesçã
@Entity
@Table(name = "messages")
public class Message {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String text;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@JoinColumn(name = "message_sender_id")
private Sender sender;
. . .
}
JPA Entity:
Tipos de dados:
- Componentes
@Embedded ou @Embeddable (Classes embutidas, as colunas da
classe embeddable ficam na Entity)
@ElementCollection (Cole o de componentes)çã
- Tipos básicos da JDK:
integer, long, short, float, double, big_decimal, big_integer,
character, string, byte, boolean, yes_no, true_false
- Date/Time:
date, time, timestamp, calendar, calendar_date
- Binary e Large Objects:
binary, text, serializable, clob, blob
- Outros tipos da JDK:
class, locale, timezone, currency
Identidade:
- @Id
Geralmente Integer ou Long
Pode ser gerado através das seguintes estratégias:
GenerationType.SEQUENCE
GenerationType.TABLE
GenerationType.IDENTITY
GenerationType.AUTO
- Quando uma entidade é igual a outra?
Implementar os métodos equals( ) e hashcode( )
equals: Deve verificar a diferen a das entidades comparando os ç
campos de acordo com o objetivo do negócio
Outras anota es:çõ
@Transient - A propriedade n o será persistidaã
@Basic - Para definir a estratégia de Fetch
@Columns - Usado para sobrescrever configura es padr o para çõ ã
colunas do banco de dados
@Lob - Usado para definir uma especializa o do tipo Lobçã
@Temporal - Usado para definir uma especializa o do tipo Dateçã
@Version Para controle de concorrência na entidade, deve ser –
usada em conjunto com uma configura o específica de Lock çã
LockModeType.OPTIMISTIC_FORCE_INCREMENT ou
LockModeType.PESSIMISTIC_FORCE_INCREMENT
public class Item implements Serializable {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id = null;
@Version
@Column(name = "OBJ_VERSION")
private int version = 0;
@Column(name = "ITEM_NAME", length = 255, nullable = false, updatable = false)
private String name;
@Embedded
@AttributeOverrides( {
@AttributeOverride(name = "street", column = @Column(name="HOME_STREET", length = 255) ),
@AttributeOverride(name = "city", column = @Column(name="HOME_CITY", length = 255) )
})
private Address homeAddress;
@Temporal(TemporalType.TIMESTAMP)
private Date created = new Date();
. . .
JPA Entity:
• Abordagem para mapeamento:
Top Down: hbm2dll
Bottom up: hbm2java
Middle out: Ambos
• Configura o:çã
persistence.xml (JPA)
hibernate.cfg.xml (Hibernate)
• Persistence Context:
Estado em que as entidades s o gerenciadas pelo JPAã
• Persistence Unit:
Unidade agrupadora de entidades e configura oçã
<persistence>
<persistence-unit name="samplePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source/>
<class>com.jboss.sample.Message</class>
<class>com.jboss.sample.Sender</class>
<exclude-unlisted-classes/>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:."/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
</properties>
</persistence-unit>
</persistence>
persistence.xml:
final EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
em.persist(new Message("Hello world");
em.getTransaction().commit();
} catch (RuntimeException relevantException) {
if (em.getTransaction().isActive()) {
try {
em.getTransaction().rollback();
} catch (PersistenceException rollBackException) {
logger.warn("Rollback of open transaction failed", RollBackException);
}
throw relevantException;
}
} finally {
em.close();
}
Entity Manager:
EntityManager:
- N o reutilizarã
- Fechar no final - close()
- Em caso de erro dar rollback na transa o çã
para liberar recursos do banco de dados
sender.setName("Correct name");
final EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Sender newSenderInstance = em.merge(sender);
em.getTransaction().commit();
em.close();
// Hibernate
Session session = (Session) em.getDelegate();
session.update(sender);
// alternatively
session.buildLockRequest(LockOptions.NONE).lock(sender);
Métodos do Entity Manager:
- Inserir:
persist( ), save( )
- Atualizar:
update( ), merge( ), saveOrUpdate( )
- Reatachar um objeto n o modificado:ã
lock( )
final EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Sender sender = em.find(Sender.class, '1');
em.remove(sender);
em.getTransaction().commit();
em.close();
// Hibernate
Session session = (Session) em.getDelegate();
Sender sender = session.get(Sender.class, '1');
session.delete(sender);
Métodos do Entity Manager:
- Remover:
remove( ), delete( )
- A entidade precisa estar atachada para ser removida.
Relacionamento de entidades:
@Embedded
@OneToOne
@OneToOne Bidirecional
@OneToMany
@OneToMany Bidirecional
@ManyToMany
@Entity
public class Address {
@OneToOne
@JoinColumn(name="user_id")
private User user;
@OneToOne:
@Entity
public class User {
@Id
@GeneratedValue(generator = "foreign_id")
private Integer id;
@OneToOne(mappedBy=”user”)
private Address address;
Exemplo 1:
Usando uma Foreign Key
Exemplo 1:
Usando o mesmo valor de Primary Key
@PrimaryKeyJoinColumn
Usa o mesmo valor de Id para ambas as tabelas
@Entity
public class Item {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SELLER_ID", nullable = false, updatable = false)
private User seller;
. . .
}
@ManyToOne e @OneToMany:
@Entity
public class User {
@OneToMany(mappedBy = "seller")
private Collection<Item> itemsForSale = new ArrayList<Item>();
. . .
}
Exemplo 1:
ManyToOne Unidirecional
Exemplo 2:
ManyToOne Bidirecional (mappedBy)
@Entity
public class Category {
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "CATEGORY_ID"),
InverseJoinColumns = @JoinColumn(name = "ITEM_ID") )
private List<Item> items = new ArrayList<Item>();
. . .
}
@ManyToMany:
@Entity
public class Item {
@ManyToMany(mappedBy="items")
private Set<Category> categories = new HashSet<Category>();
. . .
} Exemplo 1:
ManyToMany Unidirecional
Exemplo 2:
ManyToMany Bidirecional (mappedBy)
public class StudentCourse {
private StudentCourseID pk = new StudentCourseID();
@Column(name = "CAPACITY", nullable = false, length = 10)
private String capacity;
@EmbeddedId
public StudentCourseID getPk() {
return pk;
}
@ManyToMany com campo adicional:
@Embeddable
public class StudentCourseID implements java.io.Serializable {
private Student student;
private Course course;
@ManyToOne
public Course getCourse() {
return course;
}
@ManyToOne
public Student getStudent() {
return student;
}
Exemplo 1:
Classe Associativa com o campo adicional capacity
Exemplo 2:
Classe embutida definida como EmbeddableId
@Entity
public class Item {
. . .
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "ITEM_ID", nullable = false)
@org.hibernate.annotations.IndexColumn(name = "BID_POSITION")
private List<Bid> bids = new ArrayList<Bid>();
}
@IndexColumn e @OrderBy:
@Entity
public class Category implements Serializable, Comparable<Object> {
. . .
@OneToMany(mappedBy="parentCategory", cascade={CascadeType.PERSIST, CascadeType.MERGE})
@org.hibernate.annotations.OrderBy(clause="CATEGORY_NAME asc")
private List<Category> childCategories = new ArrayList<Category>();
Exemplo 1:
@IndexColumn para definir o campo índice na lista
e evitar entidades duplicadas (bag semantics)
Exemplo 2:
@OrderBy define o ordenamento padr oã
Estratégias de Heran a:ç
Table per Class:As classes s o mapeadas em uma única tabela, a coluna que ãdefine a entidade é configurada através da anota o çã@DiscriminatorColumn
Table per Subclass:Schema normalizado, cada subclasse na hierarquia tem sua própria tabela e o relacionamento é definido através de Foreign Keys.
Table per Concrete Class:Cada tabela concreta tem sua própria tabela, n o há o conceito ãde heran a a nível de banco de dados, os campos da tabela pai çs o duplicados em cada uma das tabelas.ã
Table per Class (SINGLE_TABLE):
Melhor performance✔Melhor representa o de polimorfismo✔ çãN o normalizado✘ ãRequer uma coluna para especificar o tipo de classe✘
Table per Subclass (JOINED):
Schema claro e conciso✔Totalmente normalizado✔Fácil de implementar e de entender✔Queries polimórficas podem ter um desempenho ruim se a ✘
hierarquia for muito grandeMaior dificuldade na escrita de consultas SQL✘
Table per Concrete Class (TABLE_PER_CLASS):
Sem no o de heran a a nível de banco de dados✔ çã çSem detalhes de heran a no mapeamento✔ çComplexidade em evoluir o schema✘N o suporta Queries JPA totalmente polimórficas✘ ã
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”BILLING_TYPE”, discriminatorType = DiscriminatorType.STRING)
public class BillingDetails implements Serializable, Comparable { . . . }
@Entity
public class CreditCard extends BillingDetails{ . . }
Table per Class:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class BillingDetails implements Serializable, Comparable { . . . }
@Entity
public class CreditCard extends BillingDetails{ . . }
Table per Subclass:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class BillingDetails implements Serializable, Comparable { . . . }
@Entity
public class CreditCard extends BillingDetails{ . . }
Table per Concrete Class:
Cascade:
JPA:MERGEPERSIST REMOVE REFRESHDETACH
Hibernate:MERGEPERSISTREMOVEREFRESHDELETESAVE_UPDATEREPLICATEDELETE_ORPHANLOCKEVICT
@OneToMany(cascade={javax.persistence.CascadeType.PERSIST,javax.persistence.CascadeType.MERGE})
@org.hibernate.annotations.Cascade(value = {CascadeType.SAVE_UPDATE,CascadeType.PERSIST,CascadeType.MERGE})
private Set<Item> items = new HashSet<Item>();
Fetch:
EAGER:Traz as entidades filhas quando a entidade pai é carregada.
LAZY:Traz as entidades filhas somente quando o método for
chamado (sob demanda).
@Entity public class Item { . . . @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "ITEM_ID", nullable = false) private List<Bid> bids = new ArrayList<Bid>(); . . . }
Entity Manager e ciclo de vida das entidades:
Entity Manager e ciclo de vida das entidades:
Entity Manager e ciclo de vida das entidades:
Persistence Context é o cache de 1 nível onde est o todas as ✔ º ãentidades gerenciadas pelo Hibernate
Inicia no entityManager.open() e se encerra no ✔entityManager.close()
Pode ser usado no modo extendido para escopo de ✔Conversa oçã
Faz Dirty Checking automaticamente (verifica se o objeto foi ✔alterado por outra thread antes do commit)
Sincronizado automaticamente com o banco de dados no fim ✔da transa o ou quando chamado o método flush() çã(FlushMode.AUTO), outros modos: (FlushMode.COMMIT, FlushMode.MANUAL)
É possível excluir objetos do cache através dos métodos ✔evict( ) e clear( )
Entity Manager e ciclo de vida das entidades:
Entidades passam de Transient para Persistent através do ✔save( ) ou persist( )
Entidades obtidas através de Query também s o Persistent✔ ãQuando Persistent elas s o gerenciadas e transacionais se ✔ ã
houver transa oçãPassam de Persistent para Transient através do remove( ) ou ✔
quando perdem a referência, exemplo: Orphan deleteS o detachadas através do evict( ), clear( ) ou close( )✔ ãRecarregadas do banco através do refresh( )✔
Caso de uso: Detachar / Reatachar Entitidades
Caso de uso: Modo Extendido
Transa es (ACID)çõ
Atomicidade, Consistência, Isolamento e Durabilidade✔Forma programática: ✔
Hibernate Transaction APIJPA Entity Transaction APIStandard JTA UserTransaction APIJDBC API
Forma declarativa (requer uma infraestrutura necessária):✔EJBSpringInterceptors / AOP (Customizada)
Transa esçõ
// Programática UserTransaction utx = (UserTransaction) new InitialContext().lookup(“java:comp/UserTransaction”); EntityManager em = null; try { utx.begin(); em = get().createEntityManager(); concludeAuction(session); em.flush(); utx.commit(); } . . .
// Declarativa @Stateless public class ManageAuctionBean implements ManageAuction{ @PersistenceContext private EntityManager em; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void endAuction( Item item) { em.merge(item); } }
Cache
Cache
1st level cache (sempre ativo)
Recomenda es:çõN o carregar objetos demais na memóriaãN o usar ORM para uma carga muito grande, usar Stored ãprocedures ou SQLUse scroll( ) para carregar objetos incrementalmente (cursor)Use evict( ) e clear( ) em processos batchjavax.persistence.cache.retrieveMode
CacheRetrieveMode.USECacheRetrieveMode.BYPASS
javax.persistence.cache.storeModeCacheStoreMode.USECacheStoreMode.BYPASSCacheStoreMode.REFRESH
Cache
2nd level cache
Recomenda es:çõUsar para dados compartilhados entre usuários e n o ✔ ã
específicos de um usuárioUsar para dados que mudam raramente✔Usar para dados n o críticos e que n o s o compartilhados ✔ ã ã ã
com outras aplica esçõN o utilizar para um número muito grande de objetos✔ ã
Providers:EhCacheOpenSymphony OSCacheJBossCacheInfinispan
Cache
Estratégia de Concorrência
transactionalIsolamento total acima de repeatable-read, usar quando for crítico preservar o estado dos dados em transa es çõconcorrentes
read-writeIsolamento read-commited, em ambientes n o-clusterizados, usa ãum mecanismo de timestamp para a maioria dos dados
nonstrict-read-writeN o garante a consistência, tem um tempo de expira oã çã
read-onlyPara dados que nunca mudam, dados usados como referência
Isolation-levels
SERIALIZABLELock de read e write na transa esçõSe houver colis o somente um faz o commitãNível mais alto de confiabilidade, n o ocorre phantom readsã
REPEATABLE_READLock de read e write na transa esçõPode ocorrer phantom reads (ler no início da transa o e no çã
final o dado já ter sido alterado por outra transa o)çã
READ_COMMITEDLock de read em selects e write em transa esçõPode ocorrer phantom reads, mas só lê o que foi feito commit de outras transa esçõ
READ_UNCOMMITEDN o faz lockãFaz Dirty Reads (lê dados de outras transa es que ainda n o çõ ãsofreram commit)
Estratégias de Fetch
@Fetch(FetchMode.SELECT)Estratégia default de fetch
@Fetch(FetchMode.JOIN)Traz a Entity pai e suas collections com um único select através de Join quando a Entity pai é carregada
@Fetch(FetchMode.SUBSELECT)Traz a Entity pai e suas collections com um único select através de subselect quando a Entity pai é carregada
@BatchSize(size = 10)Para cada elemento que possui uma collection, ele faz (1+n)
selects, sendo n o size da collection, o Batch vai fazer com que fa a çum select para trazer 10 elementos de uma vez ao invés de um select para cada elemento
Estratégias de Fetch
@Fetch(FetchMode.SELECT)Estratégia default de fetch
@Fetch(FetchMode.JOIN)Traz a Entity pai e suas collections com um único select através de Join quando a Entity pai é carregada
@Fetch(FetchMode.SUBSELECT)Traz a Entity pai e suas collections com um único select através de subselect quando a Entity pai é carregada
@BatchSize(size = 10)Problema: Para cada elemento que possui uma collection, ele faz
(1+n) selects, sendo n o size da collection, o Batch vai fazer com que fa a um select para trazer 10 elementos de uma vez ao invés de um çselect para cada elemento
Extra Lazy Collections
@LazyCollection(LazyCollectionOption.EXTRA)N o traz o conteúdo da collection se somente os métodos size( ) ã
ou contains( ) foram chamados.
Solu o para o problema n+1çãUsar o Fetch quando necessário de acordo com a necessidade
de negócio
// CRITERIAList results = session.createCriteria(Item.class).setFetchMode("bids", FetchMode.JOIN).list();
// HQLList results = session.createQuery("select i from Item i leftjoin fetch i.bids").list();
// DISTINCTsession.createCriteria(Item.class).setFetchMode("bids", FetchMode.JOIN).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
Tuning e melhores práticas
Um join é mais rápido que dois selects?Complexidade das queries, HQL, SQL ou Criteria? Recuperar pelo idQuantidade de hits no banco, usar cache?Compress o no cliente e no servidor ( - Memória = + CPU )ã
Onde e quais objetos devo guardar? ( escopos, 2nd level cache )@RequestScoped - Acaba no fim da requisi o, n o tem lembran açã ã ç
@ViewScoped - Escopo de tela (mantem os componentes, ajax)@SessionScoped - N o guardar listas, só dados de usuário, perfil, etc.ã
@ApplicationScoped - Comum para a aplica oçã
@Conversation - N o esquecer do @Endã
Usar DAO? Usar DTO?Usar estratégias de Fetch
Enterprise JavaBeans 3.1
Enterprise Java Beans
Session BeansMessage Driven BeansEntity Beans
Benefícios:Foco na lógica de negócio, seguran a, acesso remoto, suporte a ç
transa o e concorrência, multithreading, connection pool, gerência do çã
cico de vida dos objetos
Novidades EJB 3.1
Interfaces s o opcionaisã
Singleton BeansEJB AssíncronoTimerEJB.LiteSuporte para EJBs no servlet container (deploy de um EJB em um arquivo WAR)Suporte para Stateful Web Services via Stateful EndpointsEntity Beans = Entidades JPA
Stateful Session Beans
Mantem estado conversacional com o clienteObjetos POJO BasedPara acesso local n o é necessário implementar uma interface, ã
somente usar a anota o @Statefulçã
Se for acessado remotamente deve ser criada uma interface e anotada com @RemoteUm método deve ser anotado com @Remove para indicar onde se encerra o contexto conversacionalUtiliza por padr o o EntityManager no modo EXTENDEDã
Métodos do ciclo de vida:@PreDestroy, @PostContruct@PrePassivate, @PostActivate
Stateful Session Beans
@Statefulpublic class Cart {
List<String> items;
public ShoppingCart() {items = new ArrayList<Item>();
}
public void addItem(String item) {items.add(item);
}
public void removeItem(String item) {items.remove(item);
}
public void purchase() {// . . .
}
@Removepublic void remove() {
items = null;}
}
Stateless Session Beans
N o mantém estado conversacionalã
Objetos POJO BasedPara acesso local n o é necessário implementar uma interface, ã
somente usar anota o @Statelessçã
Se for acessado remotamente deve ser criada uma interface e anotada com @RemoteMétodos do ciclo de vida:
@PreDestroy, @PostContruct
Stateless Session Beans
@Remotepublic interface Account {
public float withdraw();public void deposit(float amount);
}
@Statelesspublic class AccountSessionBean implements Account {
public float withdraw() {// . . .
}
public void deposit(String item) {// . . .
}}
Singleton Session Beans
Instanciado uma vez na aplica o, provê acesso compartilhadoçã
Uma instância por JVM, suporte a concorrênciaN o é necessário implementar uma interface, somente usar anota o ã çã
@SingletonO Container automaticamente inicializa o EJB Singleton mas pode ser anotado com @Startup para inicializa o no modo Eagerçã
A concorrência é definida de forma declarativa em cada método com @Lock(LockType.READ) ou @Lock(LockType.WRITE)Para forma programática deve ser usado synchronized e volatileMétodos do ciclo de vida:
@PreDestroy, @PostContruct
Singleton Session Beans
@Startup@Singletonpublic class MySingleton {
public void delivery() {// . . .
}
}
Message-Driven Beans
Provê objetos de negócio para suporte a messages assíncronasJMS Based, StatelessÉ preciso implementar a interface MessageListener e utilizar a anota o @MessageDriven, a interface provê o método: onMessage( )çã
Configura o do MDB através de @ActivationConfigPropertyçã
Métodos do ciclo de vida:@PreDestroy, @PostContruct
Message-Driven Beans
@MessageDriven(mappedName="jms/Queue", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable") })public class MyMessageBean implements MessageListener {
@Overridepublic void onMessage(Message message) {
try {// process the message
} catch (JMSException ex) {// . . .
}}
}
EJB Assíncrono
Um EJB Stateless pode ser definido como assíncrono através da anota o @Asynchronousçã
A assinatura do método deve retornar a interface Future que contém na sua API a lógica para saber se o resultado está disponível através do método isDone( ) ou cancelar a execu o através do método cancel( )çã
A transa o n o é propagada nesse tipo de EJB, ent o por padr o çã ã ã ã
seus métodos sempre v o ser do tipo REQUIRES_NEWã
Métodos do ciclo de vida:@PreDestroy, @PostContruct
EJB Assíncrono
@Stateless@Asynchronouspublic class MyAsyncBean {
public Future<Integer> addNumbers(int n1, int n2) {Integer result;result = n1 + n2;// simulate a long running query. . .return new AsyncResult(result);
}}
Timers
Um EJB Timer é um servi o de execu o de tarefa agendada definido ç çã
com uma anota o @Schedule em um de seus métodos.çã
O tempo/período de execu o pode ser definido através da anota o çã çã
@Schedule ou da interface TimerServiceO método que vai fazer a execu o da tarefa pode ser o método çã
ejbTimeout(Timer t) da interface TimerService ou um método qualquer anotado com @Timeout que tenha como argumento (Timer t)Métodos do ciclo de vida:
initTimer
Timers
@Statelesspublic class MyTimer {
@Schedule(hour=”*”, minute=”*”, second=”*/10”)public void printTime( ) {
// . . .}
}
public class MyTimer implements TimedObject {@Resource TimerService timerService;
@PostConstructpublic void initTimer() {
timerService.createCalendarTimer(new ScheduleExpression().
hour(“*”).minute(“*”).second(“*/10”),
new TimerConfig(“myTimer”, true));
}}
EJB.Lite
Um EJB Lite é um componente de negócio com recursos limitados para execu o no Web Profile JavaEEçã
Nomes Globais JNDI
EJBs podem ser acessados via JNDI através de endere o global:ç
java:global[ /app-name ] /module-name /bean-name[ !fully-qualified-interface-name ]
Exemplos:java:global/bank/AccountSession ou java:global/bank/AccountSession!org.sample.AccountSessionBean
Outros nomes JNDI:java:global/bank/AccountSessionBeanjava:app/AccountSessionBeanjava:module/AccountSessionBean
Transa es - @TransactionAttributeçõ
MANDATORYSempre deve ser chamado em um contexto de transa oçã
REQUIREDSe estiver em um contexto de transa o ele propaga, se n o çã ãestiver ele cria uma nova transa oçã
REQUIRES_NEWSempre cria uma nova transa o, se já estiver em um contexto çãtransacional ele suspende e retorna após a nova transa oçã
SUPPORTSSe já existir uma transa o ele suporta, se n o existir ele n o criaçã ã ã
NOT_SUPPORTEDSe já existir uma transa o ele suspende e retorna após o métodoçã
NEVERSe já existir uma transa o ele gera javax.ejb.EJBExceptionçã
Contexts and Dependency Injection
Contexts and Dependency Injection
Mecanismo de inje o de dependências da plataforma JavaEEçã
Permite a inclus o de componentes com resolu o segura de tipos e ã çãvalida o das dependências em tempo de deploy, promove o baixo çãacoplamento tirando a responsabilidade do desenvolvedor de cuidar do componente
Um Bean CDI ao ser criado tem seu ciclo de vida gerenciado e bem definido de acordo com qual contexto foi atribuído
EJBs e outros componentes de negócio s o tratados pelo JSF como os ãManaged Beans criando uma integra o da camada Web com a camada çãtransacional
A Integra o se extende também para Expression Language (EL) çãpermitindo a qualquer objeto ser usado diretamente da camada de integra o até o JSF ou JSPçã
Defini o de um CDI Beançã
Praticamente qualquer POJO pode ser definido como Bean CDI, EJBs, Entidades JPA, recursos JNDI, basta colocar um arquivo beans.xml na pasta META-INF e cada Bean do pacote pode ser definido como um bean CDI
// Interface Shippingpublic interface Shipping {
public String rate(String name);}
// Implementa o de Shippingçãpublic class PriorityShipping implements Shipping {
public String rate(String name) {return “Hello ” + name;
}}
Pontos de Inje oçã
Um Bean é injetado usando a anota o @Inject que pode ser definida çãno campo, no método ou no construtor da classe
@Statelesspublic class ShippingService {
// Campo@Inject Shipping shipping;
. . .// Método Set
@Injectpublic setShipping(Shipping shipping) {
this.shipping = shipping;}
. . .// Construtor
@Injectpublic SimpleShipping(Shipping shipping) {
this.shipping = shipping;}
}
Qualificadores
Um Qualificador serve para dizer ao CDI qual implementa o entre çãvárias de uma determinada interface deve ser usada
public interface Shipping {public String getRate( );
}
public class ExpressShipping implements Shipping {. . . // Por padr o essa classe tem o @Default, é a implementa o padr o de Shippingã çã ã
}
public class PriorityShipping implements Shipping {. . . // Com essa implementa o o Inject n o vai funcionar pois s o duas çã ã ã // implementa es da mesma interfaceçõ
}
Qualificadores
@Qualifier @Retention(RUNTIME) @Target( { TYPE, METHOD, PARAMETER, FIELD }) public @interface Express{ } . . .
public class PriorityShipping implements Shipping {. . .
}
@Express public class ExpressShipping implements Shipping {
. . . }
As seguintes inje es podem ser usadas:çõ
@Inject Shipping shipping; -> Injeta priority @Inject @Any @Default Shipping shipping; -> Injeta pirority @Inject @Any @Express Shipping shipping; -> Injeta express @Inject @Any Shipping shipping; -> Vai dar erro
@Inject @Default Shipping shipping -> também injeta priority @Inject @Express Shipping shipping -> também injeta express
Qualificadores
@New @RequestScoped public class PriorityShipping implements Shipping {
. . . }
Ao usar o qualificar @New a classe vai para o escopo @Dependent e perde os qualificadores @Any e @Default
@Inject @New Shipping shipping;
@NamedPermite ao Bean ser acessado via EL (JSF), recomenda-se a
anota o @Named na classe e n o no ponto de inje oçã ã çã
@Default @Named public class PriorityShipping implements Shipping {
. . . }
Alternatives
Com alternatives você pode escolher qual Bean utilizar em tempo de deploy sem alterar a aplica oçã
public class PriorityShipping implements Shipping {. . .
}
@Alternative public class ExpressShipping implements Shipping {
. . . }
@Inject Shipping shipping; -> Dessa forma irá injetar PriorityShipping
Definir no beans.xml:<beans ... > <alternatives> <class>shipping.ExpressShipping</class> </alternatives></beans>
@Inject Shipping shipping; -> A Inje o agora irá injetar o ExpressShippingçã
Obs.: Se só houver a implementa o @Alternative e n o tiver definido no beans.xml a çã ãinje o n o vai funcionarçã ã
Producer e Disposer
Com alternatives você tem inje o estática, se precisar de çãinje o dinâmica você precisa usar Producerçã
@Produces public List<String> getShippings() {
List<String> response = new ArrayList<String>();return response;
}
Por padr o o escopo é @Depedent, producer pode vir com o escopo definido:ã @Produces @RequestScoped public List<String> getShippings() {
List<String> response = new ArrayList<String>();return response;
}
@Inject List<String> listShippings;
Objetos criados com Producer precisam de uma distrui o explícita @Disposes:çã
void close(@Disposes Connection connection) {connection.close();
}
Interceptors
Interceptors tem a fun o de aplicar implementa o automática çã çãem um Bean e fazer com que o código seja executado durante o ciclo de vida do objeto
@InterceptorBinding@Retention(RUNTIME)@Target({METHOD,TYPE})public @interface Logging { . . . }
@Interceptor@Loggingpublic class LoggingInterceptor {
@AroundInvoke // Irá interpor os métodos de negóciopublic Object log(InvocationContext context) throws Exception {
Logger.getLogger(getClass().getName().info(context.getMethod().getName());return context.proceed();
}}
Interceptors@Loggingpublic class ExpressShipping { . . . }
ou
public class ExpressShipping {@Loggingpublic String greet(String name) { . . . }
}
@Interceptor@Transactionalpublic class TransactionInterceptor {
@Resource UserTransaction tx;@AroundInvokepublic Object manageTransaction(InvocationContext context) {
tx.begin();Object response = context.proceed();tx.commit();return response;
}}
É preciso habilitar no beans.xml:<interceptors> <class>org.sample.TransactionInterceptor</class> </interceptors>
Decorators
Um Decorator é uma implementa o adicional ao Bean, para os çãconceitos relacionados ao negócio, contém ainda um ponto de inje o com @Delegate que indica onde ele vai delegar essa çãimplementa oçã
@Decoratorpublic abstract class ShippingDecorator implements Shipping { @Inject @Delegate @Any Shipping shipping; public String labelString(String s, int tval) { int len = s.length();
return "\"" + s + "\" label " + "\"" + coder.labelString(s, tval) + len + " length"; }}
Escopos
Um Bean é criado em um escopo e associado a um contexto, o contexto gerencia e define o seu ciclo de vida e visibilidade.
@RequestScopedDisponível durante o request, destruído quando o request tem fim.
@SessionScopedCompartilhado entre requests da mesma sess o, destruído quando a ãsess o dá timeout ou é destruida.ã
@ApplicationScopedCriado quando a aplica o sobe, destruído quando ela é derrubada.çã
@ConversationScoped: Transient e Long-running.Transient (default): O Bean é criado num request JSF e destruído no fim do request, pode ser convertido para um long-running através de Conversation.begin( ) e destruído no Conversation.end( )
@DependentPseudo-escopo, os beans que n o tem nenhum escopo declarado.ã
Stereotype
Encapsula e agrupa papéis em um único local, reduz a quantidade de anota es necessárias e cria anota es condizentes com o çõ çõBean
@Stereotype@Retention(RUNTIME)@Target(TYPE)@Transactional@Loggingpublic @interface MyShippingService { . . . }
Obs.: @Interceptor, @Decorator e @Model s o Stereotypes pré-definidos.ã
Eventos
Eventos provê um modelo de eventos baseado em anota es çõcomo o Pattern Observer, quem gera o evento e quem consome s o desacoplados e se comunicam na mudan a de estadoã ç
Definindo um evento:
@Inject @Any Event<ServiceShipping> shippingEvent;ServiceShipping service = new ServiceShipping(product, address);shippingEvent.fire(service);
Escutando o evento:
public class ProcessItems { public void processItems(@Observes ServiceShipping service) { // ... Processa os items a serem entregues. }}
Obrigado!