目录
- 一 sbt 介绍
- 1.1 Sbt
- 1.2 下载安装
- 1.3 sbt的特点
- 1.4 Idea 配置Sbt开发工具
- 二 构建定义
- 2.1 指定版本
- 2.2 build.sbt 设置
- 三 代码实现
- 3.1 Java版本
- 3.2 Scala版本
- 3.3 对比
一 sbt 介绍
1.1 Sbt
- sbt 是为 Scala 和 Java 项目构建的。它是93.6%的 Scala 开发人员的首选构建工具(2019 年)。
- sbt 可以理解为包管理工具,向maven一样来管理开发包管理工具。
1.2 下载安装
下载地址:
解压配置环境变量
SBT_HOME
PATH
- 修改配置文件
-Xmx512M
-XX:MaxPermSize=256m
-XX:ReservedCodeCacheSize=128m
-Dsbt.log.format=true
-Dsbt.override.build.repos=true
-Dconsold.encoding=UTF-8
-Dsbt.log.format=true
-Dsbt.ivy.home=D:\Environment\sbt\.ivy
-Dsbt.boot.directory=D:\Environment\sbt\boot
-Dsbt.global.base=D:\Environment\sbt\.sbt
-Dsbt.repository.config=D:\Environment\sbt\conf\repo.properties # 仓库镜像配置
- 仓库设置
[repositories]
local
huaweicloud-maven: https://repo.huaweicloud.com/repository/maven/
maven-central: https://repo1.maven.org/maven2/
sbt-plugin-repo: https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
- 验证
1.3 sbt的特点
- 简单项目需要很少或不需要配置
- 基于 Scala 的构建定义,可以充分利用 Scala 代码的灵活性
- 使用从编译器中提取的信息进行精确的增量重新编译
- 使用 Coursier 的 图书馆管理支持
- 持续编译和测试 触发执行
- 支持混合的 Scala/ Java项目
- 支持使用 ScalaCheck、specs 和 ScalaTest进行测试。JUnit 由插件支持。
- 使用类路径上的项目类和依赖项启动 Scala REPL
- 子项目支持模块化
- 外部项目支持(将 git 存储库列为依赖项!)
- 并行任务执行,包括并行测试执行
1.4 Idea 配置Sbt开发工具
- 插件安装
- SBT 软件配置
- 创建新项目
- sbt 命令窗口
二 构建定义
2.1 指定版本
- 作为构建定义的一部分,您将指定构建使用的 sbt 版本。这允许使用不同版本的 sbt 启动器的人构建具有一致结果的相同项目。为此,创建一个project/build.properties指定 sbt 版本的文件。
- 如果所需版本在本地不可用,sbt启动器将为您下载。如果此文件不存在,sbt启动器将选择一个任意版本,这是不鼓励的,因为它会使您的构建不可移植。
2.2 build.sbt 设置
# 打包构建的版本
ThisBuild / version := "0.1.0-SNAPSHOT"
# scala的版本
ThisBuild / scalaVersion := "2.11.7"
// 依赖
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.3",
"com.typesafe.akka" %% "akka-testkit" % "2.3.6" % "test",
"org.scalatest" %% "scalatest" % "2.1.6" % "test"
)
# 主入口
lazy val root = (project in file("."))
.settings(
name := "ActorDemo01"
)
三 代码实现
3.1 Java版本
- Maven依赖
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.10</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
- 编写消息实体类
/**
* @description:
* @author: shu
* @createDate: 2022/10/27 20:17
* @version: 1.0
*/
public class SetRequests {
private final String key;
private final Object value;
public SetRequests(String key, Object value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
@Override
public String toString() {
return "SetRequests{" +
"key='" + key + '\'' +
", value=" + value +
'}';
}
}
- 编写消息Actor
import akka.actor.AbstractActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.pf.ReceiveBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* @description: Java-AkkaDba
* @author: shu
* @createDate: 2022/10/27 21:13
* @version: 1.0
*/
public class AkkaDbs extends AbstractActor {
protected final LoggingAdapter log = Logging.getLogger(context().system(), this);
protected final Map<String, Object> map = new HashMap<>();
private AkkaDbs() {
receive(ReceiveBuilder
.match(SetRequests.class, message -> {
System.out.printf("收到的key:%s,value:%s%n",message.getKey(),message.getValue());
map.put(message.getKey(), message.getValue());
})
.matchAny(o -> System.out.printf("收到的消息:%s",o))
.build()
);
}
}
- 测试
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.testkit.TestActorRef;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class AkkademyDbTest {
// 获取Actor系统的引用
ActorSystem system = ActorSystem.create();
@Test
public void itShouldPlaceKeyValueFromSetMessageIntoMap() {
// 创建一个actor
TestActorRef<AkkaDbs> actorRef = TestActorRef.create(system, Props.create(AkkaDbs.class));
// 发送消息
actorRef.tell(new SetRequests("key", "value"), ActorRef.noSender());
// 我们需要检查Actor是否将值存入了map中,确认其行为是否正确
AkkaDbs akkademyDb = actorRef.underlyingActor();
assertEquals(akkademyDb.map.get("key"), "value");
}
}
3.2 Scala版本
- sbt依赖
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.11.7"
// 依赖
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.3",
"com.typesafe.akka" %% "akka-testkit" % "2.3.6" % "test",
"org.scalatest" %% "scalatest" % "2.1.6" % "test"
)
lazy val root = (project in file("."))
.settings(
name := "ActorDemo01"
)
- 消息实体类
/**
* @description: 样例类
* @author: shu
* @createDate: 2022/10/27 20:14
* @version: 1.0
*/
case class SetRequest (key:String ,value: Object);
- Actor处理中心
import akka.actor.{AbstractActor, Actor}
import akka.event.Logging
import java.util
/**
* @description: Scala-AkkaDba
* @author: shu
* @createDate: 2022/10/27 20:52
* @version: 1.0
*/
class AkkaDba extends Actor {
val map =new util.HashMap[String,Object]
val log=Logging(context.system,this);
// 接受消息
override def receive: Receive = {
// 指定的消息
case SetRequest(key,value)=>{
log.info("收到的key:{},value:{}",key,value)
map.put(key,value);
}
// 默认消息
case 0 =>{
log.info("收到一个错误的消息")
}
}
}
- 测试
import akka.actor.ActorSystem
import akka.testkit.TestActorRef
import org.scalatest.{FunSpecLike, Matchers}
class AkkademyDbSpec extends FunSpecLike with Matchers {
// 获取系统实例
implicit val system = ActorSystem()
describe("akkademyDb") {
describe("given SetRequest") {
it("should place key/value into map") {
// 创建Actor实例
val actorRef = TestActorRef(new AkkaDba)
// 发送消息
actorRef ! SetRequest("key", "123456")
// 验证消息
val akkademyDb = actorRef.underlyingActor
akkademyDb.map.get("key") should equal("123456")
}
}
}
}
3.3 对比
- ActorSystem创建方式
//Java
ActorSystem system = ActorSystem.create();
//Scala
implicit val system = ActorSystem()
- 创建Actor
//Java
TestActorRef<AkkademyDb> actorRef = TestActorRef.create(system, Props.
create(AkkademyDb.class));
//Scala
val actorRef = TestActorRef(new AkkademyDb)
- 发送消息
//Java
actorRef.tell(new SetRequest("key", "value"), ActorRef.noSender());
//Scala
actorRef ! SetRequest("key", "value")
- 检测消息
//Java
AkkademyDb akkademyDb = actorRef.underlyingActor();
assertEquals(akkademyDb.map.get("key"), "value");
//Scala
val akkademyDb = actorRef.underlyingActor
akkademyDb.map.get("key") should equal(Some("value"))
这样我们就完成了第一个简单的测试用例。这个基本的模式可以用于构建同步的Actor单元测试。