Springboot中使用Scala開發

使用SB與Scala

項目代碼

本章項目代碼:前端

https://github.com/LightSwordSpringBoot/lightswordjava

JVM上的語言家族

JVM上的語言mysql

Scala
Java
Groovy
Jython
Kotlin
Fantom
Rhino
JRuby
Ceylon
Clojure

...

1)Clojure是一個函數編程語言(functional programming language),採用類LISP語法。在處理狀態方面很擅長,且其處理方式跟Java語言徹底不一樣。儘管如此,在語法和功能上也跟Java相差太遠。git

2)Groovy是一個支持可選類型的動態語言。強依賴於Java,在不少方面都跟Java極爲相似,例如語法和代碼結構方面。這使得其很是容易上手使用。在腳本和web頁面這種須要動態元素和元程序元素(meta-programming element)方面Groovy比較擅長。其動態特性使得對於企業級服務器端核心業務邏輯開發並非一個好的選擇。程序員

3)Scala是一個OO/函數式語言,採用類C語法。深刻研究以後,你會發現其函數特性更爲明顯。這個特色會促使用戶去選擇更純粹的函數式業務邏輯解決方案。Scala採用靜態類型,其泛型設計更加具有圖靈完備性(Turing complete)。可是,用另一門語言中的泛型來寫程序是否合理呢?若是想要說清楚Scala的全部特性,那還須要一篇文章的篇幅。簡單的說,Scala對於程序員來說束縛太多。儘管第一眼看過去Scala彷佛提供了Java夢想提供給開發者的功能,可是一旦深刻了解就會發現這是個大坑。Scala不具有成爲主流編程語言的特色。github

4)Fantom是一個面嚮對象語言,也包含函數元素,採用類C語法。Fantom在不少方面的方案都簡單明瞭,例如nullable類型,非可變性(immutability)和模塊設計。其靜態類型系統採用的方式很簡單。泛型僅僅在列表(List)、映射(Map)和函數(Function)中獲得支持,開發者不能本身添加。在開發者須要添加的時候,Fantom會本身自動進行類型轉換。雖然Fantom包含主流語言應該包括的全部特性,但並無得到相應的關注。其中一個疑問是,Fantom的類型系統足夠吸引開發者嗎?web

...spring

這裡可聊的不少,在此不展開.sql

Scala簡介

Scala的設計哲學

Object-Oriented Meets Functional---當面向對象趕上函數式:apache

Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensibility, implement their behavior using higher-order functions. Or anything in-between.

典型特徵

  • 支持面向對象編程範式

  • 支持函數式編程範式

  • 語法動態簡潔表達力豐富

  • 具有靜態強類型和豐富的泛型

Scala, A Scalable language

Scala,一個可擴展的語言.

Scala精心整合了面向對象和函數式編程語言。

面向對象(Object-Oriented)

Scala是純種的面向對象的語言。從概念上講,每個值都是一個對象,每個操做都是一個方法調用。語言支持經過類和特徵的高級組件架構。

面向對象編程是一種自頂向下的程序設計方法.萬事萬物都是對象,對象有其行爲(方法),狀態(成員變量,屬性).

許多傳統的設計模式Scala已經原生支持。單例模式對應object對象定義,訪問者經過模式匹配支持。使用隱式類,Scala甚至容許你對現有類型類進行操做,不管他們來自Scala或java!

函數式編程(Functional)

Scala也是骨子裏透着函數式編程範式的語言。函數是一等公民(固然,這個在你使用面向對象編程範式風格的時候,這個函數公民也只能退後了),不可變數據結構庫等。不變性有助於編寫併發程序.

函數式編程方法經過組合和應用函數來構造邏輯系統.函數式編程傾向於把軟件分解爲其須要執行的行爲或操做,並且一般採用自底向上的方法.同時,函數式編程也提供了很是強大的對事物進行抽象和組合的能力.

Scala不執拗己見;你能夠自由使用任何你喜歡的風格。面對有多種不一樣需求的問題領域,你能夠在一個解決方案的不一樣部分,採用最適合的編程方法.

除了命令式,函數式,還有哪些其餘的編程範式?

與JVM的無縫集成(Seamless Java Interop)

Scala在JVM上運行。java和Scala類能夠自由地混合,不管他們居住在不一樣項目或同一項目。Scala能夠自由使用java庫、框架和工具。像Ant或Maven工具,IDE如Eclipse或NetBeans,框架,IntelliJ,Spring。

Scala能夠運行在全部常見的JVM, 固然還有Android OS。

甚至,Scala都想把前端JavaScript的事情也給幹了.

Scala社區是java生態系統的重要組成部分。流行的Scala框架,包括Akka, Finagle, and the Play web framework include dual APIs for Java and Scala.

函數式編程的思想是開發一個小的核心結構,可結合靈活的方式,而後進行組合。


更加豐富的scala介紹,可參考:

https://www.gitbook.com/book/universsky/scala_notes/details

使用SB與Scala開發

若是咱們使用Scala語言進行開發(或者Java,Scala混合開發,參考開源項目Spark:https://github.com/apache/spark), 而對於SpringBoot來講, 可使用任何JVM上的語言.

好比, 要使用Scala進行SpringBoot應用的開發, 須要添加Scala的相應依賴和編譯支持:

新建maven工程,添加pom依賴:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springboot.in.action</groupId>
    <artifactId>lightsword</artifactId>
    <version>1.0-SNAPSHOT</version>
    <inceptionYear>2016</inceptionYear>

    <properties>
        <scala.version>2.11.8</scala.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.compat.version>2.11</scala.compat.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <platform-bom.version>2.0.3.RELEASE</platform-bom.version>
        <spring-boot-starter-bom.version>1.0.0-SNAPSHOT</spring-boot-starter-bom.version>
        <spring-boot.version>1.3.5.RELEASE</spring-boot.version>
    </properties>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
    </parent>

    <dependencies>
        <!-- scala -->
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>

        <dependency>
            <groupId>com.typesafe.scala-logging</groupId>
            <artifactId>scala-logging-slf4j_2.11</artifactId>
            <version>2.1.2</version>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.specs2</groupId>
            <artifactId>specs2-core_${scala.compat.version}</artifactId>
            <version>2.4.16</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_${scala.compat.version}</artifactId>
            <version>2.2.4</version>
            <scope>test</scope>
        </dependency>

        <!-- sb -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-velocity</artifactId>
        </dependency>

        <!--test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.7</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.2.0</version>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <scalaVersion>${scala.version}</scalaVersion>
                    <launchers>
                        <launcher>
                            <id>app</id>
                            <mainClass>com.springboot.in.action.LightSwordApplication</mainClass>
                            <jvmArgs>
                                <jvmArg>-Xmx1024m</jvmArg>
                            </jvmArgs>
                        </launcher>
                    </launchers>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includeScope>system</includeScope>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <configuration>
                    <downloadSources>true</downloadSources>
                    <buildcommands>
                        <buildcommand>ch.epfl.lamp.sdt.core.scalabuilder</buildcommand>
                    </buildcommands>
                    <additionalProjectnatures>
                        <projectnature>ch.epfl.lamp.sdt.core.scalanature</projectnature>
                    </additionalProjectnatures>
                    <classpathContainers>
                        <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
                        <classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINER</classpathContainer>
                    </classpathContainers>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <configuration>
                    <scalaVersion>${scala.version}</scalaVersion>
                </configuration>
            </plugin>
        </plugins>
    </reporting>

    <repositories>
        <repository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <version>${platform-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

其中build中的maven-scala-plugin是編譯期依賴,scala代碼須要scala的compiler,因此在maven構建過程中,使用一個編譯scala代碼的maven插件.這是typesafe(scala背後的公司)的工程師Josh Suereth開發的,遵循maven插件開發規範.

然後,org.scala-lang:scala-library是Scala應用運行時的依賴.

這樣,我們就能夠像使用SB+java一樣來使用SB+scala來開發了.

一個最簡單的例子:

HelloController.scala

package com.springboot.in.action.controller

import java.util.Date

import com.alibaba.fastjson.JSONObject
import org.springframework.web.bind.annotation.{RequestMapping, RequestParam, RestController}

/**
 * Created by jack on 16/6/24.
 *
 * 系統內部測試用
 */

@RestController
class HelloController {

  @RequestMapping(Array("/hello"))
  def greeting(@RequestParam(value="name", defaultValue="LightSword")  name: String) = {
    val now = new Date
    val content =  "Hello, " + name + "! Now is: " + now

    val json = new JSONObject
    json.put("conent", content)

    json

  }

}

完整的工程代碼:

https://github.com/LightSwordSpringBoot/lightsword

相關文章
相關標籤/搜索