当前位置: 首页 > 科技观察

Kotlin+SpringBoot服务器开发

时间:2023-03-12 03:40:38 科技观察

什么是Kotlin?由著名IDE厂商JetBrains开发的一种基于JVM的静态类型编程语言,号称与Java100%互操作。Kotlin是由工程师设计的,各种细节设计非常适合工程师的需求。语法类似于Java和Scala,一直活跃在Android开发领域,被誉为Android平台的Swift。Kotlin可以与Java混合并直接重用Java生态系统(库、框架、工具)。现有的Java项目可以通过简单的引用Kotlin的Maven/Gradle插件,引用Kotlin标准库的依赖,逐步融入Kotlin代码。您完全可以将其视为更好的Java。Kotlin的学习曲线极其平缓,学习量相当于一个框架。有经验的程序员在阅读文档后可以立即使用它。不信你看看:原文档http://kotlinlang.org/docs/re...中文文档http://kotlindoc.com下面举几个例子来说明Kotlin的优点.No.//自动推导变量类型,无需声明vala="Hello"//简单printlnprintln(a.length()==5)//无需写new,直接调用构造函数valb=String("Hello")//字符串插值"$a$b"=="HelloHello"//if-else是一个表达式,真方便!//==相当于equals,再也不怕忘记写equals了!valoneOrTwo=if(a=="Hello")1else2//===相当于Java的==(a===b)==false//Lambda用{}包裹,如果有唯一参数,则参数名默认为它//设置函数操作,无需Java8繁琐的stream.collect(Collectors.toList())listOf(-1,0,1).map{it+1}.filter{it>0})==listOf(1,2)//使用默认值null覆盖底部valnumber=getNumberOrNull()?:0//自动关闭资源FileInputStream("MyFile").use{stream->//参数名可以是指定为stream,替换默认的valfirstByte=stream.read()}//可以更简单,一行valfileContent=File("MyFile").readText()//lazy,惰性初始化classCPU{valcpuCoresbylazy{Runtime.getRuntime(.availableProcessors()}}Kotlin厌倦了Java,怀疑Scala是喜欢Groovy但又想要静态类型的人的避风港。啊!生活。什么是弹簧引导?SpringBoot是一个流行的快速Web开发框架,可以让基于Spring的开发变得更加方便。我们已经知道Spring好用,SpringBoot的设计目标是:为所有Spring开发提供开箱即用的快速通用体验,但不会阻止您在默认值时进行更改不符合您的需求。为各种项目类型(如嵌入式服务器、安全、指标、健康检查、外部配置)提供一套适用的非功能性特性无需代码生成和XML配置Kotlin+SpringBootKotlin可以轻松集成SpringBoot,如何写进去Java,使用Kotlin基本上是怎么写的。Spring可以在线生成项目,省去了创建项目的麻烦,请点击链接http://start.spring.io/。我们使用Gradle构建并编写一个build.gradle文件:spring-boot-gradle-plugin:${springBootVersion}")classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")}}applyplugin:'kotlin'applyplugin:'spring-boot'jar{baseName='myapp'version='0.1-SNAPSHOT'}sourceCompatibility=1.8targetCompatibility=1.8//class文件保留参数名compileJava.options.compilerArgs.add'-parameters'compileTestJava.options.compilerArgs.add'-parameters'springBoot{mainClass='myapp.ApplicationKt'}dependencies{compile'org.springframework.boot:spring-boot-starter-aop'compile'org.springframework.boot:spring-boot-starter-web'compile'org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"}先写一个主类Application.kt,放到src/main/kotlin目录下(自己想个包名),启动整个应用:@SpringBootApplicationopenclassApplication{@Beanopenfunjson():MappingJackson2JsonView{returnMappingJackson2JsonView(ObjectMapper())}}funmain(args:Array){SpringApplication.run(Application::class.java,*args)}Kotlin函数可以在类外定义,特殊的main函数可以是放在外面,或者放在伴生对象(companionobject)里面,放在外面这里!你会发现class和fun前面有一个open修饰符,表示非final。Kotlin默认情况下一切都是最终的。如果你不想保存final要添加打开。由于Spring有时需要创建代理,要求类和方法不能是final的,所以我们处处写open,以免忘记。这里只有一个json()方法,用来在Spring中初始化Jackson,这样我们就可以使用JSON了。现在让我们编写一个RestController来提供一个RESTfulAPI:@RestController@RequestMapping("/api/users")openclassUserApi{@RequestMapping("/{id}",method=arrayOf(RequestMethod.GET))openfunget(@PathVariableid:Long)="User(id=$id,name=admin,password=123)"}就是这么简单!现在,在IDE中运行Application.kt文件,它将开始运行!用浏览器打开http://localhost:8080/api/use...现在是时候将数据存入数据库了:SpringBoot使用JPA非常简单(从官网入门学习),但是我想介绍另一个ORM框架——Ebean,它模仿ActiveRecordforRails支持常见的JPA注解。值得一提的是,Ebean的作者也很喜欢Kotlin。需要一个配置文件src/main/resources/ebean.properties:#是否生成表SQLebean.db.ddl.generate=true#是否执行表SQLebean.db.ddl.run=falsedatasource.db.username=DB用户名datasource.db.password=DB密码datasource.db.databaseUrl=jdbc:mysql://localhost:3306/你的数据库名datasource.db.databaseDriver=com.mysql.jdbc.Driver我们有ebean.db.ddl。run(是否执行SQL建表)selectfalse。因为Ebean会生成建表SQL,我们可以手动执行,避免每次都重新建表,丢掉数据。写完实体类然后运行,会在项目目录下生成SQL,手动执行!(也可以在***启动前把ebean.db.ddl.run改成true)然后在Spring中初始化Ebean://在Application类中添加这个方法@Bean(autowire=Autowire.BY_TYPE)openfungetEbeanServer():EbeanServer{valconfig=ServerConfig()config.name="db"config.loadFromProperties()config.isDefaultServer=truereturnEbeanServerFactory.create(config)}然后修改main方法,执行Spring之前的Ebean代理,重写实体的字节码class:funmain(args:Array){valpackageName="com.iostate.**"//改成自己的包名,实体类要放在这个包里面if(!AgentLoader.loadAgentFromClasspath("avaje-ebeanorm-agent","debug=1;packages=$packageName")){System.err.println("avaje-ebeanorm-agentnotfoundinclasspath-notdynamicallyloaded")}SpringApplication.run(Application::class.java,*args)}Ebean需要执行代理重写字节码(instrumenation),而Hibernate则选择为实体对象创建一个动态代理(dynamicproxy),所有这些都是为了对实体执行AOP操作。仪器使用复杂且易于调试;动态代理易于使用但调试复杂。各有千秋,我更赞同重写字节码。编写实体类:importjavax.persistence.*importcom.avaje.ebean.Modelimportcom.avaje.ebean.annotation.WhenCreatedimportcom.avaje.ebean.annotation.WhenModifiedimportjava.sql.Timestampimportcom.avaje.ebean.annotation.SoftDeleteimportcom.fasterxml.jackson.annotation.JsonIgnore@MappedSuperclassabstractclassBaseModel:Model(){@Id@GeneratedValuevarid:Long=0@Versionvarversion:Long=0@WhenCreatedvarwhenCreated:Timestamp?=null@WhenModifiedvarwhenModified:Timestamp?=null}@EntityclassUser(varname:String="",@JsonIgnorevarpassword:String=""@SoftDeletevardeleted:Boolean=false):BaseModel(){companionobjectfind:Find()}第一个类是所有实体模型的基类,提供一些公共字段。id是自增主键,version是乐观锁标志,whenCreated是创建时间,whenModified是修改时间。有些变量类型以问号结尾,这和Swift语言一样,表示可以为null(默认为non-null)。第二类是User,行数很少,没有繁琐的getter/setter。@JsonIgnore的作用是防止敏感字段泄露到JSON中,@SoftDelete的作用是软删除(数据不可见,但不是真正删除)。companionobjectfind:Find()提供了一组快捷查询方法,比如byId(id)all()。现在修改UserApi如下:@RestController@RequestMapping("/api/users")openclassUserApi{@RequestMapping("/{id}",method=arrayOf(RequestMethod.GET))openfunget(@PathVariableid:Long)=User.byId(id)@RequestMapping("/new",method=arrayOf(RequestMethod.POST))openfuncreate(@RequestParamname:String,@RequestParampassword:String):User{returnUser(name,password).apply{save()}}}get方法其实是查询数据库的!新增create方法,用于创建用户!如果想用浏览器快速测试,把RequestMethod.POST改成GET,输入链接http://localhost:8080/api/use...TryTry!注意事项SpringBoot可以将程序打包成jar直接运行,对广大群众来说非常方便!但是JSP和Ebean都不能工作在jar模式下。那么在生产环境中如何解决呢?您可以解压并运行jar!参考文档的解压包:http://docs.spring.io/spring-...#Unzipunzip-qmyapp.jar#Runjavaorg.springframework.boot.loader.JarLauncher#生产模式使用如下nohup方法,以防程序随shell一起关闭nohupjavaorg.springframework.boot.loader.JarLauncher&我使用不同的命令:unzip-qmyapp.jarnohupjava-cp'.:./lib/*'com.myapp.ApplicationKt&注意当前工作目录,日志目录/logs将在当前工作目录中创建。我提供了一个示例工程,比较粗糙,还请多多包涵https://github.com/sorra/bms还有几个老外的示例工程,供参考:SpringBootKotlinprojectwithaRESTWebserviceandSpringData:https://github.com/sdeleuze/s...使用SpringBoot、Kotlin和React.js的演示Webapp:https://github.com/winterbe/s...顺便说一下,LightRealm是用Kotlin构建的+SpringBoot的!