SlideShare uma empresa Scribd logo
1 de 60
Bernhard Wenzel
www.bernhardwenzel.com
Using Spring with Scala
Spring I/O
2016
Overview
1.Introduction & Motivation
2.Practical examples
3.Evaluation
4.Questions
Spring I/O
2016
Target audience
• Developers with Java/Spring background
• Scala curious or beginner
Spring I/O
2016
Why Spring + Scala?
Spring I/O
2016
Why Spring + Scala?
Spring I/O
2016
Why Scala?
• For fun
• Learning a new language makes me a better
developer
• Functional Programming!
• For profit
• Scala is (becoming) popular: LinkedIn, Guardian,
Twitter, many more ...
Spring I/O
2016
What I like about Scala
(as a Java dev)
• Code tends to be more concise
• Scala was built for FP from ground up
• In Scala I can mix OO + FP
• Java interop allows to move gradually towards
Scala
• Java 8 is catching up (e.g. Lambdas) but Scala still
has many other features (e.g. Pattern matching)
Spring I/O
2016
Why Scala & Spring
• Learning a new language is enough, I’d like to keep
my favourite frameworks & tools (SpringBoot,
Gradle)
• New languages come with new frameworks that are
unproven
• I want to gradually introduce Scala into my existing
Java&Spring project
Spring I/O
2016
2. Examples
www.spring.io/guides
Spring I/O
2016
Translated guides from Java to Scala
• Copy & Paste of Java files into Scala dir
• Transformed each .java into .scala
• Kept Gradle as build tool
• Source code available at GitHub
(github.com/BernhardWenzel/spring-scala-
examples)
Spring I/O
2016
First example: serving web content
with Spring MVC
Spring I/O
2016
Make Gradle work with Scala
build.gradle
...
apply plugin: 'scala'
apply plugin: 'application'
mainClassName = "hello.Application"
...
dependencies {
...
compile 'org.scala-lang:scala-library:2.11.1'
...
}
Spring I/O
2016
Application class
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
class Application {
}
object Application extends App {
SpringApplication.run(classOf[Application], args:_*)
}
Spring I/O
2016
Template
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>
Spring I/O
2016
Controller
@Controller
public class GreetingController {
@RequestMapping("/greeting")
public String greeting(
@RequestParam(value="name",required=false) String name,
Model model) {
model.addAttribute("name", name);
return "greeting";}}
@Controller
class GreetingController {
@RequestMapping(Array("/greeting"))
def greeting(
@RequestParam(value="name", required=false) name: String,
model: Model) : String = {
model.addAttribute("name", name)
"greeting"
}}
Spring I/O
2016
That’s it
$ gradle run
. . .
2016-05-06 16:05:52.644 INFO 1297 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat
2016-05-06 16:05:52.650 INFO 1297 --- [ restartedMain] scala.App$class : Started App.class in
$ curl http://localhost:8080/greeting?name=SpringIO
<!DOCTYPE HTML>
<html>
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>Hello, SpringIO!</p>
</body>
</html>
Spring I/O
2016
Translation steps:
• Gradle: add scala plugin (optional application)
• Application class: split into companion object in
Scala and run with args:_*
• Controller: @RequestMapping annotation need to
convert String into Array(String)
Spring I/O
2016
Example: consuming REST
services
Spring I/O
2016
Beans in Java
Value.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {
private Long id;
private String quote;
public Long getId() {return this.id;}
public String getQuote() {return this.quote;}
public void setId(Long id) {this.id = id;}
public void setQuote(String quote) {this.quote = quote;}
@Override
public String toString() {
return "Value{" +
"id=" + id +
", quote='" + quote + ''' +
'}';
}}
Spring I/O
2016
Beans in Scala
Value.scala
@JsonIgnoreProperties(ignoreUnknown = true)
class Value {
@BeanProperty
var id: Long = _
@BeanProperty
var quote: String = _
override def toString : String =
"Value{id=" + id +", quote=" + quote +"}"
}
Spring I/O
2016
Application class
public void run(String... args) throws Exception {
RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random",
Quote.class);
log.info(quote.toString());
}
override def run(args: String*): Unit = {
val restTemplate = new RestTemplate()
val quote : Quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random",
classOf[Quote])
log.info(quote.toString)
}
Spring I/O
2016
Asynchronous version using Lambdas
Application.java
AsyncRestTemplate asyncTemplate = new AsyncRestTemplate();
final ListenableFuture<ResponseEntity<Quote>> quoteFuture = asy
"http://gturnquist-quoters.cfapps.io/api/random",
Quote.class);
quoteFuture.addCallback(
success -> log.info("async: " + quote),
failure -> log.error("Async error", failure));
void addCallback(
SuccessCallback<? super T> successCallback,
FailureCallback failureCallback);
Spring I/O
2016
Java 8 Lambdas vs.
Scala function literals
(a:Int, b:Int) => a + b
Scala function literal
(Integer a, Integer b) -> a + b
Java 8 lambdas
Spring I/O
2016
Asynchronous version
Application.scala
quoteFuture.addCallback(
(success: SuccessCallback[ResponseEntity[Quote]])
=> log.info("async: " + quote),
(failure: FailureCallback)
=> log.error("Async error",failure))
Spring I/O
2016
Asynchronous version
Scala functions =! Java Lambdas
quoteFuture.addCallback(
(success: SuccessCallback[ResponseEntity[Quote]])
=> log.info("async: " + quote),
(failure: FailureCallback)
=> log.error("Async error",failure))
Application.scala
Spring I/O
2016
We need ugly anonymous classes
Application.scala
quoteFuture.addCallback(new ListenableFutureCallback[ResponseEntit
override def onSuccess(entity : ResponseEntity[Quote]) : Unit =
log.info("async: " + entity.getBody.toString)
override def onFailure(t : Throwable) : Unit =
log.error("Async error", t)
})
Spring I/O
2016
Works in Scala
$ gradle run
. ____ _ __ _ _
/ / ___'_ __ _ _(_)_ __ __ _    
( ( )___ | '_ | '_| | '_ / _` |    
/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.3.RELEASE)
…
2016-05-02 11:44:49.052 INFO 3702 --- [ main] hello.Application : async: Quote{type='success'
over configuration, providing an experience on par with frameworks that excel
at early stage development, such as Ruby on Rails.}}
…
BUILD SUCCESSFUL
Spring I/O
2016
Translation steps
• Beans: use @BeanProperty annotation
• Java 8 Lambdas != Scala function literals, in Scala
have to use anonymous classes
Spring I/O
2016
Providing REST API using Spring Data
Rest
Spring I/O
2016
Person resource in Scala
@Entity
class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@BeanProperty
var id: Long = _
@BeanProperty
var firstName: String = _
@BeanProperty
var lastName: String = _
}
Spring I/O
2016
Repository
@RepositoryRestResource(collectionResourceRel = "people",
path = "people")
public interface PersonRepository
extends PagingAndSortingRepository<Person, Long> {
List<Person> findByLastName(@Param("name") String name);
}
@RepositoryRestResource(collectionResourceRel = "people",
path = "people")
trait PersonRepository
extends PagingAndSortingRepository[Person, Long] {
def findByLastName(@Param("name") name: String):
List[Person]
}
Spring I/O
2016
Oops…
PersonRepository.scala:8: type arguments [hello.Person,Long]
do not conform to trait PagingAndSortingRepository's type
parameter bounds [T,ID <: java.io.Serializable]
trait PersonRepository extends
PagingAndSortingRepository[Person, Long] {
scala.Long != java.lang.Long
Spring I/O
2016
Repository
PersonRepository.scala
@RepositoryRestResource(collectionResourceRel = "people",
path = "people")
trait PersonRepository
extends PagingAndSortingRepository[Person, java.lang.Long] {
def findByLastName(@Param("name") name: String):
List[Person]
}
Explicitly refer to Java base type
import java.lang.Long
Spring I/O
2016
Spring Data Rest in Scala
$ curl http://localhost:8080
{
"_links" : {
"people" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile"
}
}
}
Spring I/O
2016
Translation steps
• When using Java/Spring interface, beware of Java
base types
Spring I/O
2016
Final example: JDBC
public void run(String... strings) throws Exception {
jdbcTemplate.execute("DROP TABLE customers IF EXISTS");
jdbcTemplate.execute("CREATE TABLE customers(" +
"id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255)
// Split up the array of whole names into an array of
// first/last names
List<Object[]> splitUpNames = Arrays
.asList("John Woo", "Jeff Dean", "Josh Bloch",
"Josh Long“)
.stream()
.map(name -> name.split(" "))
.collect(Collectors.toList());
. . .
Spring I/O
2016
JDBC: Java Batch Update
// Use a Java 8 stream to print out each tuple of the list
splitUpNames.forEach(
name -> log.info(String.format(
Inserting customer record for %s %s",
name[0], name[1])));
// Uses JdbcTemplate's batchUpdate operation to
// bulk load data
jdbcTemplate.batchUpdate(
"INSERT INTO customers(first_name, last_name) VALUES (?,?)",
splitUpNames);
log.info("Querying for customer records where first_name = 'Josh':");
Spring I/O
2016
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers " +
"WHERE first_name = ?",
new Object[] { "Josh" },
(rs, rowNum) ->
new Customer(
rs.getLong("id"),
rs.getString("first_name"),
rs.getString("last_name"))
).forEach(customer -> log.info(customer.toString()));
public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
public <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper)
JDBC: Java Query
Spring I/O
2016
override def run(args: String*): Unit = {
jdbcTemplate.execute("DROP TABLE customers IF EXISTS")
jdbcTemplate.execute("CREATE TABLE customers("id SERIAL,
first_name VARCHAR(255), last_name VARCHAR(255))“)
JDBC Scala create tables
Spring I/O
2016
JDBC Scala names
collection
import scala.collection.mutable.ListBuffer
val splitUpNames = ListBuffer(
"John Woo", "Jeff Dean", "Josh Bloch", "Josh Long“)
.map(_.split(" "))
splitUpNames.foreach(name => log.info(
"Inserting customer record for %s %s".format(name(0), name(1))))
Scala: collections are immutable
java.util.List <-> scala.collection.mutable.Buffer
Spring I/O
2016
jdbcTemplate.batchUpdate(
"INSERT INTO customers(first_name, last_name) VALUES (?,?)“,
splitUpNames
.asInstanceOf[mutable.Buffer[Array[AnyRef]])
JDBC Scala batchUpdate
java.lang.Object <-> scala.AnyRef
List<Object[]> <-> mutable.Buffer[Array[AnyRef]]
public int[] batchUpdate(String sql, List<Object[]> batchArgs)
Spring I/O
2016
JDBC Scala batchUpdate
Still a Scala collection
jdbcTemplate.batchUpdate(
"INSERT INTO customers(first_name, last_name) VALUES (?,?)“,
splitUpNames
.asInstanceOf[mutable.Buffer[Array[AnyRef]])
java.lang.Object <-> scala.AnyRef
List<Object[]> <-> mutable.Buffer[Array[AnyRef]]
public int[] batchUpdate(String sql, List<Object[]> batchArgs)
Spring I/O
2016
Convert from Scala
JavaConverters.asJava <- Scala
import collection.JavaConverters._
jdbcTemplate.batchUpdate(
"INSERT INTO customers(first_name, last_name) VALUES (?,?)“,
splitUpNames
.asInstanceOf[mutable.Buffer[Array[AnyRef]].asJava)
Spring I/O
2016
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?",
Array("Josh").asInstanceOf[Array[AnyRef]],
new RowMapper[Customer]{
override def mapRow(rs: ResultSet, rowNum: Int): Customer =
new Customer(
rs.getLong("id"),
rs.getString("first_name"),
rs.getString("last_name"))
})
JDBC Scala query
(again casting Object -> AnyRef)
(again implement anonymous class)
Spring I/O
2016
JDBC Scala print query
Returns Java collection
jdbcTemplate.query(
. . .
).foreach(…)
Spring I/O
2016
import collection.JavaConverters._
jdbcTemplate.query(
. . .
).asScala
.foreach((customer:Customer)
=> log.info(customer.toString))
Convert from Java
Java -> JavaConverters.asScala
Spring I/O
2016
Works in Scala
$ gradle run
. ____ _ __ _ _
/ / ___'_ __ _ _(_)_ __ __ _    
( ( )___ | '_ | '_| | '_ / _` |    
/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.3.RELEASE)
...[main] hello.Application: Creating tables
...[main] hello.Application: Inserting customer record for John Woo
...[main] hello.Application: Inserting customer record for Jeff Dean
...[main] hello.Application: Inserting customer record for Josh Bloch
...[main] hello.Application: Inserting customer record for Josh Long
...[main] hello.Application: Querying for customer records where first_name = 'Josh':
...[main] hello.Application: Customer[id=3, firstName=Josh, lastName=Bloch]
...[main] hello.Application: Customer[id=4, firstName=Josh, lastName=Long]
Spring I/O
2016
Translation steps
• Use Scala mutable collection when calling Java
• Type casting
• Java Object/Scala AnyRef,
• Java []/Scala Array
• Java List/Scala Buffer
• Collection transformations asJava and asScala
Spring I/O
2016
3. Evaluation
Spring I/O
2016
We „just“ need to translate from Scala to Java
and vice versa
3. Evaluation
Good news: it works!
Spring I/O
2016
Spring I/O
2016
Simple translation steps
• add Scala plugin to Gradle
• Application class requires object
• add Array to @Annotations(Array(…))
• Fields of beans require @BeanProperty annotation
Spring I/O
2016
Slightly annoying translation steps
• Avoiding Scala base types for Sprint interfaces
• Casting to/from Java (e.g. Java Object to Scala
AnyRef)
• Requiring scala.JavaTransformations toJava and
toScala with collections
• Using Scala mutable collections when interacting
with Java
Spring I/O
2016
Annoying translation step
• Can’t use Scala functions as Java 8 Lamdbas
Spring I/O
2016
Annoying translation step
Will work in Scala 2.12
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?",
Array("Josh").asInstanceOf[Array[AnyRef]],
(rs: ResultSet, rowNum: Int) =>
new Customer(
rs.getLong("id"),
rs.getString("first_name"),
rs.getString("last_name")))
• Can’t use Scala functions as Java 8 Lamdbas
Spring I/O
2016
Scala SDK is getting better dealing with Java
• Additional frameworks?
• e.g. defunct (Pivotal) Spring-Scala project
• Eases some issues, e.g. no @BeanProperty
necessary
• Better to be consistent across all Java
dependencies
Spring I/O
2016
Conclusion
• It works. Spring is just another Java framework that
I can use from Scala
Spring I/O
2016
Conclusion
• Drawbacks using Spring instead of pure Scala
framework:
• not always able to write most idiomatic Scala
code
• translation from/to Java can be annoying
sometimes
Spring I/O
2016
Conclusion
• Advantages:
• I can keep my Spring productivity & use a well
proven framework while focusing on Scala
features
• Scala SDK constantly improving Java interop so
current issues can be expected to become
obsolete
Spring I/O
2016
Thank you
• Source code available at Github:
github.com/BernhardWenzel/spring-scala-examples
• Slides and talk online:
bernhardwenzel.com/blog/2016/04/22/using-spring-
with-scala/
Contact:
• http://bernhardwenzel.com
• twitter: @bernhardwenzel

Mais conteúdo relacionado

Semelhante a Using Spring with Scala

Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...
Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...
Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...Julian Hyde
 
Scala Presentation Work
Scala Presentation WorkScala Presentation Work
Scala Presentation WorkSkills Matter
 
Have You Seen Spring Lately?
Have You Seen Spring Lately?Have You Seen Spring Lately?
Have You Seen Spring Lately?Joshua Long
 
Scala & sling
Scala & slingScala & sling
Scala & slingmichid
 
the Spring Update from JavaOne 2013
the Spring Update from JavaOne 2013the Spring Update from JavaOne 2013
the Spring Update from JavaOne 2013Joshua Long
 
Designing CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsDesigning CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsNeil Crookes
 
03 form-data
03 form-data03 form-data
03 form-datasnopteck
 
Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & ClientsPokai Chang
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardJAX London
 
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
 Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data... Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...Big Data Spain
 
Alpine academy apache spark series #1 introduction to cluster computing wit...
Alpine academy apache spark series #1   introduction to cluster computing wit...Alpine academy apache spark series #1   introduction to cluster computing wit...
Alpine academy apache spark series #1 introduction to cluster computing wit...Holden Karau
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Sven Efftinge
 
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...Databricks
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 

Semelhante a Using Spring with Scala (20)

Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...
Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...
Planning with Polyalgebra: Bringing Together Relational, Complex and Machine ...
 
Scala Presentation Work
Scala Presentation WorkScala Presentation Work
Scala Presentation Work
 
Have You Seen Spring Lately?
Have You Seen Spring Lately?Have You Seen Spring Lately?
Have You Seen Spring Lately?
 
Scala & sling
Scala & slingScala & sling
Scala & sling
 
Scala presentationjune112011
Scala presentationjune112011Scala presentationjune112011
Scala presentationjune112011
 
the Spring Update from JavaOne 2013
the Spring Update from JavaOne 2013the Spring Update from JavaOne 2013
the Spring Update from JavaOne 2013
 
Designing CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsDesigning CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIs
 
03 form-data
03 form-data03 form-data
03 form-data
 
Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & Clients
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
 
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
 Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data... Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
 
Alpine academy apache spark series #1 introduction to cluster computing wit...
Alpine academy apache spark series #1   introduction to cluster computing wit...Alpine academy apache spark series #1   introduction to cluster computing wit...
Alpine academy apache spark series #1 introduction to cluster computing wit...
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...
Spark Machine Learning: Adding Your Own Algorithms and Tools with Holden Kara...
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 

Último

Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 

Último (20)

Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 

Using Spring with Scala

  • 2. Spring I/O 2016 Overview 1.Introduction & Motivation 2.Practical examples 3.Evaluation 4.Questions
  • 3. Spring I/O 2016 Target audience • Developers with Java/Spring background • Scala curious or beginner
  • 6. Spring I/O 2016 Why Scala? • For fun • Learning a new language makes me a better developer • Functional Programming! • For profit • Scala is (becoming) popular: LinkedIn, Guardian, Twitter, many more ...
  • 7. Spring I/O 2016 What I like about Scala (as a Java dev) • Code tends to be more concise • Scala was built for FP from ground up • In Scala I can mix OO + FP • Java interop allows to move gradually towards Scala • Java 8 is catching up (e.g. Lambdas) but Scala still has many other features (e.g. Pattern matching)
  • 8. Spring I/O 2016 Why Scala & Spring • Learning a new language is enough, I’d like to keep my favourite frameworks & tools (SpringBoot, Gradle) • New languages come with new frameworks that are unproven • I want to gradually introduce Scala into my existing Java&Spring project
  • 10. Spring I/O 2016 Translated guides from Java to Scala • Copy & Paste of Java files into Scala dir • Transformed each .java into .scala • Kept Gradle as build tool • Source code available at GitHub (github.com/BernhardWenzel/spring-scala- examples)
  • 11. Spring I/O 2016 First example: serving web content with Spring MVC
  • 12. Spring I/O 2016 Make Gradle work with Scala build.gradle ... apply plugin: 'scala' apply plugin: 'application' mainClassName = "hello.Application" ... dependencies { ... compile 'org.scala-lang:scala-library:2.11.1' ... }
  • 13. Spring I/O 2016 Application class @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @SpringBootApplication class Application { } object Application extends App { SpringApplication.run(classOf[Application], args:_*) }
  • 14. Spring I/O 2016 Template <!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Getting Started: Serving Web Content</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p th:text="'Hello, ' + ${name} + '!'" /> </body> </html>
  • 15. Spring I/O 2016 Controller @Controller public class GreetingController { @RequestMapping("/greeting") public String greeting( @RequestParam(value="name",required=false) String name, Model model) { model.addAttribute("name", name); return "greeting";}} @Controller class GreetingController { @RequestMapping(Array("/greeting")) def greeting( @RequestParam(value="name", required=false) name: String, model: Model) : String = { model.addAttribute("name", name) "greeting" }}
  • 16. Spring I/O 2016 That’s it $ gradle run . . . 2016-05-06 16:05:52.644 INFO 1297 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat 2016-05-06 16:05:52.650 INFO 1297 --- [ restartedMain] scala.App$class : Started App.class in $ curl http://localhost:8080/greeting?name=SpringIO <!DOCTYPE HTML> <html> <head> <title>Getting Started: Serving Web Content</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p>Hello, SpringIO!</p> </body> </html>
  • 17. Spring I/O 2016 Translation steps: • Gradle: add scala plugin (optional application) • Application class: split into companion object in Scala and run with args:_* • Controller: @RequestMapping annotation need to convert String into Array(String)
  • 19. Spring I/O 2016 Beans in Java Value.java @JsonIgnoreProperties(ignoreUnknown = true) public class Value { private Long id; private String quote; public Long getId() {return this.id;} public String getQuote() {return this.quote;} public void setId(Long id) {this.id = id;} public void setQuote(String quote) {this.quote = quote;} @Override public String toString() { return "Value{" + "id=" + id + ", quote='" + quote + ''' + '}'; }}
  • 20. Spring I/O 2016 Beans in Scala Value.scala @JsonIgnoreProperties(ignoreUnknown = true) class Value { @BeanProperty var id: Long = _ @BeanProperty var quote: String = _ override def toString : String = "Value{id=" + id +", quote=" + quote +"}" }
  • 21. Spring I/O 2016 Application class public void run(String... args) throws Exception { RestTemplate restTemplate = new RestTemplate(); Quote quote = restTemplate.getForObject( "http://gturnquist-quoters.cfapps.io/api/random", Quote.class); log.info(quote.toString()); } override def run(args: String*): Unit = { val restTemplate = new RestTemplate() val quote : Quote = restTemplate.getForObject( "http://gturnquist-quoters.cfapps.io/api/random", classOf[Quote]) log.info(quote.toString) }
  • 22. Spring I/O 2016 Asynchronous version using Lambdas Application.java AsyncRestTemplate asyncTemplate = new AsyncRestTemplate(); final ListenableFuture<ResponseEntity<Quote>> quoteFuture = asy "http://gturnquist-quoters.cfapps.io/api/random", Quote.class); quoteFuture.addCallback( success -> log.info("async: " + quote), failure -> log.error("Async error", failure)); void addCallback( SuccessCallback<? super T> successCallback, FailureCallback failureCallback);
  • 23. Spring I/O 2016 Java 8 Lambdas vs. Scala function literals (a:Int, b:Int) => a + b Scala function literal (Integer a, Integer b) -> a + b Java 8 lambdas
  • 24. Spring I/O 2016 Asynchronous version Application.scala quoteFuture.addCallback( (success: SuccessCallback[ResponseEntity[Quote]]) => log.info("async: " + quote), (failure: FailureCallback) => log.error("Async error",failure))
  • 25. Spring I/O 2016 Asynchronous version Scala functions =! Java Lambdas quoteFuture.addCallback( (success: SuccessCallback[ResponseEntity[Quote]]) => log.info("async: " + quote), (failure: FailureCallback) => log.error("Async error",failure)) Application.scala
  • 26. Spring I/O 2016 We need ugly anonymous classes Application.scala quoteFuture.addCallback(new ListenableFutureCallback[ResponseEntit override def onSuccess(entity : ResponseEntity[Quote]) : Unit = log.info("async: " + entity.getBody.toString) override def onFailure(t : Throwable) : Unit = log.error("Async error", t) })
  • 27. Spring I/O 2016 Works in Scala $ gradle run . ____ _ __ _ _ / / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.3.3.RELEASE) … 2016-05-02 11:44:49.052 INFO 3702 --- [ main] hello.Application : async: Quote{type='success' over configuration, providing an experience on par with frameworks that excel at early stage development, such as Ruby on Rails.}} … BUILD SUCCESSFUL
  • 28. Spring I/O 2016 Translation steps • Beans: use @BeanProperty annotation • Java 8 Lambdas != Scala function literals, in Scala have to use anonymous classes
  • 29. Spring I/O 2016 Providing REST API using Spring Data Rest
  • 30. Spring I/O 2016 Person resource in Scala @Entity class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) @BeanProperty var id: Long = _ @BeanProperty var firstName: String = _ @BeanProperty var lastName: String = _ }
  • 31. Spring I/O 2016 Repository @RepositoryRestResource(collectionResourceRel = "people", path = "people") public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { List<Person> findByLastName(@Param("name") String name); } @RepositoryRestResource(collectionResourceRel = "people", path = "people") trait PersonRepository extends PagingAndSortingRepository[Person, Long] { def findByLastName(@Param("name") name: String): List[Person] }
  • 32. Spring I/O 2016 Oops… PersonRepository.scala:8: type arguments [hello.Person,Long] do not conform to trait PagingAndSortingRepository's type parameter bounds [T,ID <: java.io.Serializable] trait PersonRepository extends PagingAndSortingRepository[Person, Long] { scala.Long != java.lang.Long
  • 33. Spring I/O 2016 Repository PersonRepository.scala @RepositoryRestResource(collectionResourceRel = "people", path = "people") trait PersonRepository extends PagingAndSortingRepository[Person, java.lang.Long] { def findByLastName(@Param("name") name: String): List[Person] } Explicitly refer to Java base type import java.lang.Long
  • 34. Spring I/O 2016 Spring Data Rest in Scala $ curl http://localhost:8080 { "_links" : { "people" : { "href" : "http://localhost:8080/people{?page,size,sort}", "templated" : true }, "profile" : { "href" : "http://localhost:8080/profile" } } }
  • 35. Spring I/O 2016 Translation steps • When using Java/Spring interface, beware of Java base types
  • 36. Spring I/O 2016 Final example: JDBC public void run(String... strings) throws Exception { jdbcTemplate.execute("DROP TABLE customers IF EXISTS"); jdbcTemplate.execute("CREATE TABLE customers(" + "id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255) // Split up the array of whole names into an array of // first/last names List<Object[]> splitUpNames = Arrays .asList("John Woo", "Jeff Dean", "Josh Bloch", "Josh Long“) .stream() .map(name -> name.split(" ")) .collect(Collectors.toList()); . . .
  • 37. Spring I/O 2016 JDBC: Java Batch Update // Use a Java 8 stream to print out each tuple of the list splitUpNames.forEach( name -> log.info(String.format( Inserting customer record for %s %s", name[0], name[1]))); // Uses JdbcTemplate's batchUpdate operation to // bulk load data jdbcTemplate.batchUpdate( "INSERT INTO customers(first_name, last_name) VALUES (?,?)", splitUpNames); log.info("Querying for customer records where first_name = 'Josh':");
  • 38. Spring I/O 2016 jdbcTemplate.query( "SELECT id, first_name, last_name FROM customers " + "WHERE first_name = ?", new Object[] { "Josh" }, (rs, rowNum) -> new Customer( rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name")) ).forEach(customer -> log.info(customer.toString())); public interface RowMapper<T> { T mapRow(ResultSet rs, int rowNum) throws SQLException; } public <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper) JDBC: Java Query
  • 39. Spring I/O 2016 override def run(args: String*): Unit = { jdbcTemplate.execute("DROP TABLE customers IF EXISTS") jdbcTemplate.execute("CREATE TABLE customers("id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))“) JDBC Scala create tables
  • 40. Spring I/O 2016 JDBC Scala names collection import scala.collection.mutable.ListBuffer val splitUpNames = ListBuffer( "John Woo", "Jeff Dean", "Josh Bloch", "Josh Long“) .map(_.split(" ")) splitUpNames.foreach(name => log.info( "Inserting customer record for %s %s".format(name(0), name(1)))) Scala: collections are immutable java.util.List <-> scala.collection.mutable.Buffer
  • 41. Spring I/O 2016 jdbcTemplate.batchUpdate( "INSERT INTO customers(first_name, last_name) VALUES (?,?)“, splitUpNames .asInstanceOf[mutable.Buffer[Array[AnyRef]]) JDBC Scala batchUpdate java.lang.Object <-> scala.AnyRef List<Object[]> <-> mutable.Buffer[Array[AnyRef]] public int[] batchUpdate(String sql, List<Object[]> batchArgs)
  • 42. Spring I/O 2016 JDBC Scala batchUpdate Still a Scala collection jdbcTemplate.batchUpdate( "INSERT INTO customers(first_name, last_name) VALUES (?,?)“, splitUpNames .asInstanceOf[mutable.Buffer[Array[AnyRef]]) java.lang.Object <-> scala.AnyRef List<Object[]> <-> mutable.Buffer[Array[AnyRef]] public int[] batchUpdate(String sql, List<Object[]> batchArgs)
  • 43. Spring I/O 2016 Convert from Scala JavaConverters.asJava <- Scala import collection.JavaConverters._ jdbcTemplate.batchUpdate( "INSERT INTO customers(first_name, last_name) VALUES (?,?)“, splitUpNames .asInstanceOf[mutable.Buffer[Array[AnyRef]].asJava)
  • 44. Spring I/O 2016 jdbcTemplate.query( "SELECT id, first_name, last_name FROM customers WHERE first_name = ?", Array("Josh").asInstanceOf[Array[AnyRef]], new RowMapper[Customer]{ override def mapRow(rs: ResultSet, rowNum: Int): Customer = new Customer( rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name")) }) JDBC Scala query (again casting Object -> AnyRef) (again implement anonymous class)
  • 45. Spring I/O 2016 JDBC Scala print query Returns Java collection jdbcTemplate.query( . . . ).foreach(…)
  • 46. Spring I/O 2016 import collection.JavaConverters._ jdbcTemplate.query( . . . ).asScala .foreach((customer:Customer) => log.info(customer.toString)) Convert from Java Java -> JavaConverters.asScala
  • 47. Spring I/O 2016 Works in Scala $ gradle run . ____ _ __ _ _ / / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.3.3.RELEASE) ...[main] hello.Application: Creating tables ...[main] hello.Application: Inserting customer record for John Woo ...[main] hello.Application: Inserting customer record for Jeff Dean ...[main] hello.Application: Inserting customer record for Josh Bloch ...[main] hello.Application: Inserting customer record for Josh Long ...[main] hello.Application: Querying for customer records where first_name = 'Josh': ...[main] hello.Application: Customer[id=3, firstName=Josh, lastName=Bloch] ...[main] hello.Application: Customer[id=4, firstName=Josh, lastName=Long]
  • 48. Spring I/O 2016 Translation steps • Use Scala mutable collection when calling Java • Type casting • Java Object/Scala AnyRef, • Java []/Scala Array • Java List/Scala Buffer • Collection transformations asJava and asScala
  • 50. Spring I/O 2016 We „just“ need to translate from Scala to Java and vice versa 3. Evaluation Good news: it works!
  • 52. Spring I/O 2016 Simple translation steps • add Scala plugin to Gradle • Application class requires object • add Array to @Annotations(Array(…)) • Fields of beans require @BeanProperty annotation
  • 53. Spring I/O 2016 Slightly annoying translation steps • Avoiding Scala base types for Sprint interfaces • Casting to/from Java (e.g. Java Object to Scala AnyRef) • Requiring scala.JavaTransformations toJava and toScala with collections • Using Scala mutable collections when interacting with Java
  • 54. Spring I/O 2016 Annoying translation step • Can’t use Scala functions as Java 8 Lamdbas
  • 55. Spring I/O 2016 Annoying translation step Will work in Scala 2.12 jdbcTemplate.query( "SELECT id, first_name, last_name FROM customers WHERE first_name = ?", Array("Josh").asInstanceOf[Array[AnyRef]], (rs: ResultSet, rowNum: Int) => new Customer( rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))) • Can’t use Scala functions as Java 8 Lamdbas
  • 56. Spring I/O 2016 Scala SDK is getting better dealing with Java • Additional frameworks? • e.g. defunct (Pivotal) Spring-Scala project • Eases some issues, e.g. no @BeanProperty necessary • Better to be consistent across all Java dependencies
  • 57. Spring I/O 2016 Conclusion • It works. Spring is just another Java framework that I can use from Scala
  • 58. Spring I/O 2016 Conclusion • Drawbacks using Spring instead of pure Scala framework: • not always able to write most idiomatic Scala code • translation from/to Java can be annoying sometimes
  • 59. Spring I/O 2016 Conclusion • Advantages: • I can keep my Spring productivity & use a well proven framework while focusing on Scala features • Scala SDK constantly improving Java interop so current issues can be expected to become obsolete
  • 60. Spring I/O 2016 Thank you • Source code available at Github: github.com/BernhardWenzel/spring-scala-examples • Slides and talk online: bernhardwenzel.com/blog/2016/04/22/using-spring- with-scala/ Contact: • http://bernhardwenzel.com • twitter: @bernhardwenzel