Le duo Spring et Scala en 20 minutes

Réunir le duo "Scala" et "Spring" dans une démo est une belle entreprise.
Combiner le meilleur des deux rapidement est une expérience excitante!:)
A Netapsys, Spring est bien présent dans tous les projets J2EE.
Scala aura-t-il le même sort? Ce qui est sûr, Scala a tous les atouts pour.

Sur le net, bien que ce sujet est peu abordé mais vous trouvez ici un article intéressant sur ce thème.
Ce billet vous présente une démo qui montre comment, en 20 minutes, réaliser cette expérience (magique :)).

La démo reprend l'exemple d'envoi de mail (voir ici) que je recommande sa lecture :).

Passons aux choses pratiques...

Prérequis:
Ajouter au projet scala créé sous eclipse les dépendances :

spring-2.5.6.jar, spring-test-2.5.6.jar,  jsr250-api-1.0.jar, 
mail-1.2.4.jar, activation-1.1.jar,
Junit-4.4.jar, commons-loggings-1.1.1.jar.

NOTE. Les numéros de versions sont données à titre indicative.
Je recommande JUnit-4.4 afin d'éviter un bug connu dans la suivante.

ACTE 1: Fichier de Spring

Créer un fichier xml et placer le dans le répertoire src.
Ce fichier ne contient qu'une seule déclaration du bean JavaMailSender de l'API Spring.

 
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	
 <context:component-scan base-package=
    "fr.netapsys.blog.simulatemail" />	
 <bean id="javaMailSender" 
  class="org.springframework.mail.javamail.JavaMailSenderImpl">
   <property name="host" value="localhost" />
 </bean>
</beans>

ACTE 2: Un trait IMailSender

Le code scala du trait (interface) est:

 
package fr.netapsys.blog.springmail
trait IMailSender {
  def send(to:String,from:String,body:String)
  def send(to:String,from:String,subject:String,body:String)
}

Rien à dire de particulier. un trait bien ordinaire!.

ACTE 3: Une classe MailSender

MailSender est la seule classe (service) scala qui gère l'envoi de mail.
Elle étend le trait "IMailSender"
Elle s'appuie sur l'API Spring org.springframework.mail.javamail.Spring JavaMailSender.
Voici le contenu de MailSender.scala:

 
package fr.netapsys.blog.springmail
import javax.mail.internet.MimeMessage
import org.springframework.mail.javamail._
import org.springframework.stereotype.Service
import javax.annotation.Resource
@Service("mailSender")
class MailSender  extends IMailSender {
var javaMailSender:JavaMailSender=null
def send(to: String, from: String,subject:String, body: String){
    javaMailSender.send( 
       new MimeMessagePreparator() {
	 override def prepare( mimeMessage:MimeMessage) {
	  val helper = new MimeMessageHelper(mimeMessage, false)
	  helper.setTo(to); helper.setFrom(from)
	  helper.setSubject("NO SUBJECT!!")
	  if(subject!=null) helper.setSubject(subject)
	  helper.setText(body, true)
	}		
    }
 )
}

 def send(to: String, from: String, body: String)=
                 send(to,from,null,body)
  
 @Resource
 def setJavaMailSender(jMailSender:JavaMailSender) {
  this.javaMailSender = jMailSender;
 }
}

Comme en java, voir billet, la méthode send de JavaMailSender prend en argument
l'interface MimeMessagePreparator ayant une seule méthode nommée
prepare surchargée dans ce code.
Ce qui explique la présence du terme réservé "override" devant def prepare.
L'annotation de Spring @Service permet d'injecter ce service comme nous le verrons
dans la classe object "Main" ci-après.
Le setter annoté avec @Resource permet d'injecter la variable JavaMailSender.

ACTE 4: Une classe Main avec simulation de l'envoi

 
package fr.netapsys.blog.springmail
import javax.annotation.Resource
import org.springframework.mail.javamail._
import org.springframework.context.support._
import org.springframework.context.ApplicationContext

object Main extends App{
//init Spring AppContext
val ctx:ApplicationContext = new 
    ClassPathXmlApplicationContext("spring-mail.xml")
// get the only bean from spring ctx
val mailSender:IMailSender= 
    ctx.getBean("mailSender").asInstanceOf[IMailSender]
//call method send
mailSender.send("a.c@n.fr","from@from.fr",
     "Scala and Spring form a couple of shock!")
}

Avant d'exécuter ce "Main", télécharger smtp.jar
Déposer ce jar dans un répertoire nommons-le SMTP_REP.
Dans SMTP_REP, lancer avec la console Dos, la commande "jar -java smtp.jar" et laisser la console ouverte.
Le billet détaille ce point.
Enfin, dans eclipse, clic droit sur "Main" Run as Scala Application.
Les résultats sont affichés dans la console Dos et des fichiers logs sont rajoutés dans le répertoire SMTP_REP.
C'est la fonction "send" ayant trois arguments qui est utilisée dans le "Main".
Voilà, j'ai bien dit que c'était simple mais surtout rapide.
Vous avez le meilleur de Spring et de Scala entre vos mains.

Et si on évoque les "Closures" dans scala, les "Free variable" et les 'Open Terms"?
Ah non! on va laisser tout ça à une prochaine fois disons après le bronzage de l'été:)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.