softshake 2014 - Java EE

Post on 17-Dec-2014

255 views 2 download

description

Le temps est révolu où Java EE ne serait qu’à développer des applications de mise à jour de données, avec JSF / EJB / JPA. Aujourd’hui Java EE s’est assoupli et s’est ouvert sur le monde, avec CDI comme clé de voûte et a repoussé nos limites grâce à des capacités d’extension puissantes et faciles d’utilisation comme JCA. Dans un premier temps, nous reviendrons rapidement sur la place de CDI dans JavaEE 7 et sur ses mécanismes d’extension. Dans un deuxième temps, nous verrons les techniques de connecteurs JCA et comment ils peuvent aussi constituer une possibilité d’ouverture simple à mettre en œuvre. JCA fournit des techniques pour gérer des connexions sortantes ou entrantes, sur des formats ou protocoles variés.

Transcript of softshake 2014 - Java EE

Avec JavaEE, fais ce que tu veux…

Alexis Hassler

Alexis Hassler• Développeur, formateur Java

• Indépendant

• Co-leader du

• @AlexisHassler

Java EE1° partie

http://www.public-domain-image.com/

CDI

Java EEJSF

EJB 3

JPA

JAX-RSWebSocket

CDI

JCA

MQTT

Broker

Consumer

Consumer

Consumer

Producer

Producer

Producer

Topic

Topic

Topic

Topic

SubscribePublish

MQTT

http://www.galuzzi.it/

MQTT

http://commons.wikimedia.org/wiki/File:St_Jude_Medical_pacemaker_with_ruler.jpg

MQTT

JCA2° partie

http://www.public-domain-image.com/

Java Connector

Architecture

Java EE

EISApp

Con

nect

or

Java EE

Outbound

Java EE

EISApp

Con

nect

or

Java EE

App

Dat

aSou

rce

Resourcepublic class SomeNiceBean { @Resource(name="jdbc/SomeDS") DataSource dataSource; public void doTheJob() { Connection connection = dataSource.getConnection(); ... }}

MQTT Connection Factory

public class SomeNiceBean { @Resource(name="mqtt/QuestionCF") ConnectionFactory connectionFactory; public void doTheJob() { connectionFactory.getConnection() .publish(message); }}

ImplementationAPI

ManagedConnection Factory

ConnectionFactory

ManagedConnectionConnection

Resource Adapter

ManagedConnection Factory

ConnectionFactorynew

ManagedConnection

new

ConnectionManager

Connection

ResourceAdapter

new

ConnectionEventListener XAResource

LocalTransaction

ManagedConnectionMetaData

Inbound

Java EE

App

Con

nect

or

EIS

Message Driven Bean

Java EE

MDBJMS

Destination

Con

nect

or

JMS Message Driven Bean

@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName="destinationLookup", propertyValue="swt/Question"), @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), }) public class MyJmsBean implements MessageListener { @Override public void onMessage(Message message) { ... } }

MQTT Message Driven Bean

@MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName = "topicName", propertyValue = "swt/Question") } ) public class MyMqttBean implements MqttListener { @Override public void onMessage(Message message) { ... } }

ImplementationAPI

ResourceAdapterListener

ActivationSpecMessage

XAResource

WorkerManager

BootstrapContext

Connector APIpublic interface MqttListener { void onMessage(Message message); }

public class Message { private byte[] payload; public Message(byte[] payload) { this.payload = payload; } // + Getter}

Message Driven Bean ++@MessageDrivenpublic class MyMqttBean implements MqttListener { @TopicName("swt/Question") public void onQuestion(Message message) { ... }

@TopicName("swt/Answer") public void onAnswer(Message message) { ... }

}

Connector

mqtt-ra.rar

Application(w. MDB)

mqtt-ra-example.war

WildFly

MQTTBroker

(mosquitto)

MQTT Clientmosquitto pub/sub

C D I3° partie

http://www.picturesdepot.com/

Context & Dependency Injection

• IoC pour Java EE et Java SE

• Gestion des contextes

• Liant pour la plupart des spec Java EE

• Moteur d’extensions pour Java EE

http://commons.wikimedia.org/

Bean

@Inject

Dependency Injection

public class MessageService { @Override public String message() { return "Bonjour le monde !"; } }

Dependency Injectionpublic class HelloBean { @Inject MessageService service; public void displayHello() { display( frService.message() ); } }

Highlander Rule

there can be only one

http://pixabay.com/

Qualifiers

public class EnglishMessageService implements MessageService { public String message() { return "Hello World!"; } }

public class FrenchMessageService implements MessageService { public String message() { return "Bonjour le monde !"; } }

Qualifiers

@Qualifier@Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER})public @interface English {}

@Qualifier@Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER})public @interface French {}

Qualifiers

@English public class EnglishMessageService implements MessageService { public String message() { return "Hello World!"; } }

@French public class FrenchMessageService implements MessageService { public String message() { return "Bonjour le monde !"; } }

Qualifiers

public class HelloBean { @Inject @French MessageService service; public void displayHello() { display(service.message()); } }

Programmatic Lookup

http://pixabay.com/

Programmatic lookuppublic class HelloBean { @Inject Instance<MessageService> service; public void displayHello() { if (! service.isUnsatisfied()) { display(service.get().message()); } } }

Programmatic lookuppublic class HelloBean { @Inject @Any Instance<MessageService> services; public void displayHello() { for (MessageService service : services) { display(service.message()); } } }

Contexts

@ApplicationScopedpublic class MessageService { ... }

@RequestScoped@ConversationScoped@SessionScoped

@Dependent

Decorators@Decorator@Priority(Interceptor.Priority.APPLICATION) public class MessageDecorator implements MessageService { @Inject @Delegate @Any MessageService service; public String message() { return service.message() + " -decorated"; } }

http://pixabay.com/

Interceptors

http://commons.wikimedia.org/

Interceptors

@InterceptorBinding@Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Loggable {}

Interceptors@Interceptor @Loggablepublic class LogInterceptor { @AroundInvoke public Object log(InvocationContext ic) throws Exception { System.out.println("Entering " + ic.getMethod().getName()); try { return ic.proceed(); } finally { System.out.println("Exiting " + ic.getMethod().getName()); } }}

Interceptors

@Loggablepublic class HelloBean { @Inject MessageService service; public void displayHello() { display(service.message()); } }

Producers

http://commons.wikimedia.org/

Producers

public class FacesProducer { @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); } }

Producers

@Produces public Logger produceLogger( InjectionPoint injectionPoint) { String loggerName = injectionPoint .getMember() .getDeclaringClass() .getName(); return Logger.getLogger(loggerName); }

public class HelloBean { @Inject MessageService service; @Inject Event<Message> messageEvent; public void displayHello() { display(service.message()); messageEvent.fire( new Message(frService.message())); } }

Events

Events

public class MessageReceiver { public void receive(@Observes Message message) { System.out.println("Received: " + message.text); } }

Synthèse

ContextInjection

Decoration Interception Event JavaEE Integration

Portable Extension

CDI Portable Extensions

Bean Manager

https://www.kingbean.com/

Bean Manager• Interagir avec le conteneur CDI• Lecture seule

• Injectable

• JNDI• java:comp/BeanManager

public class HelloBean { @Inject BeanManager beanManager; ...}

Extension•Manipuler les métadonnées du container• AnnotatedType

• InjectionPoint / InjectionTarget

• BeanAttributes / Beans

• Producer, Observer

• Pendant le démarrage

Comment ?En observant les

événements déclenchés par le

conteneur CDI

Exemple (-)• Exclure les entités JPA

public class VetoEntityExtension implements Extension { public void vetoEntity( @Observes @WithAnnotations({Entity.class}) ProcessAnnotatedType<?> pat) { pat.veto(); }

}

Exemple (+)• Ajouter un bean

public class HashMapAsBeanExtension implements Extension { public void addHashMapAsAnnotatedType( @Observes BeforeBeanDiscovery bbd, BeanManager beanManager) { bbd.addAnnotatedType( beanManager.createAnnotatedType(HashMap.class) ); } }

CDI 1.1 LifecycleBefore Bean Discovery

Process BeanProcess

Annotated Type

ScanArchive

ApplicationRunning

After Deployment Validation

Before Shutdown

Undeploy Application

Process Producer

After Bean Discovery

ProcessInjection Target

Process Observer Method

ProcessInjection

Point

Process Bean Attributes

After Type Discovery

événement unique

événements multiples

étape interne

Deployment starts

Bean eligibility

check

Application

mqtt-cdi-example.war

WildFly

MQTTBroker

(mosquitto)

MQTT Clientmosquitto pub/sub

http://pixabay.com/

4° partieJCA // CDI

CDI

JCA

Managed Connection Factory

@ConnectionDefinition (connectionFactory = MqttConnectionFactoryImpl.class, connectionFactoryImpl = MqttConnectionFactoryImpl.class, connection = BlockingConnection.class, connectionImpl = BlockingConnection.class) public class MqttManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation, Serializable { @Inject ResourceAdapter ra;

}

JCA

CDI

public class SomeNiceBean { @Inject MqttConnectionFactory connectionFactory; public void doTheJob() { Connection connection = connectionFactory.getConnection(); ... }}

javax.enterprise.inject. UnsatisfiedResolutionException

Java EE 8• Implicit Producers ?

• Ambiguities ?

• Qualifiers ?

JCA // CDI

JCA

ManagedConnection Factory

ConnectionFactorynew

ManagedConnection

new

ConnectionManager

Connection

ResourceAdapter

new

ConnectionEventListener

XAResource

LocalTransaction

ManagedConnectionMetaData

WorkerManager

CDIUserTransaction

ManagedExecutorService

ConnectionFactory Producer

ConnectionFactorynew

ConnectionLocalTransaction

Outbound Connector

JCA < CDI

Message Driven Bean@MqttDrivenpublic class MyMqttBean { @TopicName("swt/Question") public void onQuestion(Message message) { ... }

@TopicName("swt/Answer") public void onAnswer(Message message) { ... }

}

Message Observer@ApplicationScopedpublic class MyMqttBean { public void onQuestion( @Observes @TopicName(value = "swt/Question") Message message) { ... } public void onAnswer( @Observes @TopicName("swt/QuestionBis") Message message) { ... }

}

Threads

https://www.flickr.com/photos/mckaysavage/6491930649/

Inbound Connector

JCA > CDI

Java EE Application Server

App

CDI

App

CDI

App

CDI

JCA

?http://pixabay.com/fr/point-d-interrogation-boule-demande-65833/

Exemples• https://github.com/antoinesd/cdi-demo

• https://github.com/sewatech/mqtt-ra/

• https://github.com/hasalex/mqtt-cdi

• http://fr.slideshare.net/sewatech/

Version longue• Part 1 : Intro + CDI• https://parleys.com/play/536749d1e4b04bb59f502706

• Part 2 : JCA + Synthèse• https://parleys.com/play/5369f1f9e4b04bb59f502725