针对java9系列(二)docker运行java9和docker运行java程序这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展5分钟学会Java9-Java11的七大新特性、5分钟学会Ja
针对java9 系列 (二) docker 运行 java9和docker运行java程序这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展5分钟学会Java9-Java11的七大新特性、5分钟学会Java9的WebSocket 客户端api、AG 百家家乐正规网址《 787977.tv 飞机 @gb560 》一路走到 java 工程师,java 都快出 java9 了,到底该如何学 java?、docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)等相关知识,希望可以帮助到你。
本文目录一览:- java9 系列 (二) docker 运行 java9(docker运行java程序)
- 5分钟学会Java9-Java11的七大新特性
- 5分钟学会Java9的WebSocket 客户端api
- AG 百家家乐正规网址《 787977.tv 飞机 @gb560 》一路走到 java 工程师,java 都快出 java9 了,到底该如何学 java?
- docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)
java9 系列 (二) docker 运行 java9(docker运行java程序)
序
本文介绍下如何在 docker 运行 java9
镜像
docker pull openjdk:9-jdk
启动
docker run -it openjdk:9-jdk /bin/jshell
然后就可以正常使用 jshell 了,比如
Sep 22, 2017 2:16:12 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 9-Debian
| For an introduction type: /help intro
jshell> Arrays.asList(1,2,3,4).stream().limit(3).forEach(e -> System.out.print(e))
123
退出
jshell> /exit
| Goodbye
查看此镜像的 java 版本
docker run -it openjdk:9-jdk /bin/bash
root@44d1d18351a8:/# java -version
openjdk version "9-Debian"
OpenJDK Runtime Environment (build 9-Debian+0-9b181-4)
OpenJDK 64-Bit Server VM (build 9-Debian+0-9b181-4, mixed mode)
doc
- Start using Java 9 shell — jshell with docker
5分钟学会Java9-Java11的七大新特性
现在Java有多元化的发展趋势,既有JS又有C++还有C#的影子,不学习那是不行滴。
来来来,花5分钟看看Java9-Java11的七大新特性,还有代码样例。
Java11 发布了,然而很多公司还在用Java 8 ,这里简单介绍一下 Java 9 -11 引入的新语法和API。
本地变量类型推断
Java 10 就已经引入了新关键词var,该关键词可以在声明局部变量的时候替换类型信息。本地(local)是指方法内的变量声明。 Java 10之前,你需要这样声明一个String对象。
在Java10里头可以使用var替代String,表达式变成这样:
用var声明的变量仍然是静态类型的。 不兼容的类型无法重新分配给此类变量。 此代码段无法编译:
当编译器无法推断出正确的变量类型时,也不允许使用var。 以下所有代码示例都会导致编译器错误:
局部变量类型推断可以泛型。 在下一个示例中,Map <String,List <Integer >>类型,可以将其简化为单个var关键字,从而避免大量样板代码:
从Java 11开始,lambda参数也允许使用var关键字:
HTTP Client
Java 9开始引入HttpClient API来处理HTTP请求。 从Java 11开始,这个API正式进入标准库包(http://java.net)。 让我们来探索一下我们可以用这个API做些什么。 新的HttpClient可以同步或异步使用。 同步请求会阻止当前线程。 BodyHandlers定义响应体的预期类型(例如,字符串,字节数组或文件):
也可以使用异步来执行相同的请求。 调用sendAsync不会阻止当前线程,而是返回CompletableFuture来进行异步操作。
我们可以省略.GET(),因为它是默认的请求方法。
下一个示例通过POST将数据发送到给定的URL。 与BodyHandler类似,您使用BodyPublishers定义作为请求主体发送的数据类型,如字符串,字节数组,文件或输入流:
最后一个例子演示了如何通过BASIC-AUTH执行授权:
Collections
List,Set和Map等集合已经用新方法扩展。 List.of从给定的参数创建了一个新的不可变列表。 List.copyOf创建列表的不可变副本。
因为list已经是不可变的,所以实际上不需要实际创建list实例的副本,因此list和副本是相同的实例。 但是,如果你复制一个可变list,那么复制确实会生成一个新实例,因此保证在改变原始list时没有副作用:
创建不可变map时,您不必自己创建map条目,而是将键和值作为参数传递:
Java 11中的不可变集合仍然使用Collection API中的老接口。 但是,如果尝试修改不可变集合,则会抛出java.lang.UnsupportedOperationException。 可喜的是,如果尝试改变不可变集合,Intellij IDEA会通过发出警告
Streams
Streams是在Java 8中引入的,Java 9增加了三个新方法。 单个参数构造方法:
增加 takeWhile 和 dropWhile 方法,用于从stream中释放元素:
如果对Stream不熟,可以参考这篇文章[1]。
Optionals
Optionals提供了一些非常方便的功能,例如 您现在可以简单地将Optional转换为Stream,或者为空Optinal提供另一个Optional作为备胎:
Strings
Java11 给String增加了一些辅助方法来修剪或检查空格等功能:
InputStreams
InputStream增加了transferTo方法,可以用来将数据直接传输到 OutputStream:
其他的一些VM特性 从Java 8 到 Java 11引入了很多新特性,以下是这些特性的列表:
· Flow API for reactive programming
· Java Module System
· Application Class Data Sharing
· Dynamic Class-File Constants
· Java REPL (JShell)
· Flight Recorder
· Unicode 10
· G1: Full Parallel Garbage Collector
· ZGC: Scalable Low-Latency Garbage Collector
· Epsilon: No-Op Garbage Collector
· Deprecate the Nashorn JavaScript Engine
译者注:对于译者来说还是Application Class-Data Sharing(CDS),ZGC和Flight Recorder比较有吸引力一点。关于ZGC,可以参考前段时间高可用架构关于ZGC的文章。
原文地址:
https://winterbe.com/posts/20...
本文作者Benjamin,由方圆翻译。转载自公众号高可用架构
网易云信,你身边的即时通讯和音视频技术专家,了解我们,请戳网易云信官网
想要阅读更多行业洞察和技术干货,请关注网易云信博客
更多精彩内容,关注网易云信知乎机构号哦。
5分钟学会Java9的WebSocket 客户端api
初体验Java9的WebSocket 客户端api
最近开始学习高版本的JDK。花了点儿时间学习了jdk9中http和websocket的api。
虽然这俩是jdk9的东西,但是我本地学习环境实际上是JDK13,可能高版本的API有一些小的变化
以前如果需要java实现的websocket客户端。要么自己写(我没那么本事)实现协议,要么用第三方的框架。例如优秀牛逼的: Netty
谢天谢地的是jdk提供了这一系列的api。
主要的类库
WebSocket ws的客户端接口,主要职责是消息发送,连接关闭,设置监听器
Builder 用于创建 WebSocket
实例的Builder接口
Listener 用于监听连接事件,消息事件,异常事件,关闭事件的监听器接口
Builder & Listener 都是以内部接口的形式,定义在 WebSocket 类中的
源码 & 注释
package java.net.http;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public interface WebSocket {
// 正常关闭的消息code
int NORMAL_CLOSURE = 1000;
// WebSocket的builder
interface Builder {
// 设置header
Builder header(String name, String value);
// 设置链接超时时间
Builder connectTimeout(Duration timeout);
// 设置子协议
Builder subprotocols(String mostPreferred, String... lesserPreferred);
// 异步的创建链接,并且设置监听器
CompletableFuture<WebSocket> buildAsync(URI uri, Listener listener);
}
// 消息监听器
interface Listener {
// 监听连接就绪事件
default void onOpen(WebSocket webSocket) { webSocket.request(1); }
// 监听文本消息事件
default CompletionStage<?> onText(WebSocket webSocket,
CharSequence data,
boolean last) {
webSocket.request(1);
return null;
}
// 监听二进制消息事件
default CompletionStage<?> onBinary(WebSocket webSocket,
ByteBuffer data,
boolean last) {
webSocket.request(1);
return null;
}
// 监听心跳事件
default CompletionStage<?> onPing(WebSocket webSocket,
ByteBuffer message) {
webSocket.request(1);
return null;
}
default CompletionStage<?> onPong(WebSocket webSocket,
ByteBuffer message) {
webSocket.request(1);
return null;
}
// 监听关闭事件
default CompletionStage<?> onClose(WebSocket webSocket,
int statusCode,
String reason) {
return null;
}
// 监听异常事件
default void onError(WebSocket webSocket, Throwable error) { }
}
// 发送文本,二进制,心跳,关闭消息。都是异步的
CompletableFuture<WebSocket> sendText(CharSequence data, boolean last);
CompletableFuture<WebSocket> sendBinary(ByteBuffer data, boolean last);
CompletableFuture<WebSocket> sendPing(ByteBuffer message);
CompletableFuture<WebSocket> sendPong(ByteBuffer message);
CompletableFuture<WebSocket> sendClose(int statusCode, String reason);
// 统计消息数量
void request(long n);
String getSubprotocol();
boolean isOutputClosed();
boolean isInputClosed();
void abort();
}
看完了,是不是觉得贼简单? :grinning:
通过 HttpClient 创建 WebSocket 的 Builder
HttpClient,可以理解为一个浏览器
WebSocket.Builder builder = HttpClient.newBuilder()
.build() // 先通过 Builder 创建 HttpClient 对象
.newWebSocketBuilder() // 调用对象的 newWebSocketBuilder 方法创建 WebSocket 的Builder
实例
使用 Netty 提供一个 WebSocket 的服务,客户端连接上后,循环发送消息。服务端收到消息后,转换到大写返回给客户端。
当服务端收到超过10条消息后,就给客户端返回 "bye"消息,由客户端主动来断开与服务端的链接。
客户端
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.net.http.WebSocket.Listener;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
/**
*
* @author KevinBlandy
*
*/
public class Client implements Test{
public static void main(String[] args) throws Exception {
// 执行线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
// 创建监听器
WebSocket.Listener listener = new Listener() {
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
String message = data.toString();
System.out.println("收到服务器消息:" + message + ",是否是最后一帧:" + last);
if (last) {
// 完整的一条消息,才纳入消息数量统计
webSocket.request(1);
}
if (message.equalsIgnoreCase("bye")) {
// 收到服务端的 "byte", 客户端主动断开链接
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "byte").whenComplete((websocket, throable) -> {
// 资源释放
executor.shutdown();
System.out.println("已经关闭和服务端的channel");
});
}
return null;
}
};
// 创建websocket的builder
HttpClient.newBuilder()
.executor(executor)
.build()
.newWebSocketBuilder()
.buildAsync(new URI("ws://localhost:1024/channel"), listener).whenComplete((webSocket, throable) -> {
while (true) {
webSocket.sendText("Hello: " + System.currentTimeMillis(), true);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
public static void json(Object object) {
System.out.println(JSON.toJSONString(object, SerializerFeature.PrettyFormat));
}
}
服务端
import java.net.InetSocketAddress;
import java.util.Locale;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.Attribute;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.AttributeKey;
/**
*
* websocket server
*
* @author KevinBlandy
*
*/
public class Server {
static final String ENDPOINT = "/channel";
public static void main(String[] args) throws InterruptedException {
AttributeKey<Integer> count = AttributeKey.valueOf("count");
EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();
EventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.localAddress(new InetSocketAddress("0.0.0.0", 1024));
serverBootstrap.childHandler(new ChannelInitializer<>() {
@Override
protected void initChannel(Channel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof FullHttpRequest) {
FullHttpRequest fullHttpRequest = (FullHttpRequest) msg;
String uri = fullHttpRequest.uri();
if (!uri.equals(ENDPOINT)) {
ctx.channel().writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND))
.addListener(ChannelFutureListener.CLOSE);
return ;
}
}
super.channelRead(ctx, msg);
}
});
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(ENDPOINT, null, true));
pipeline.addLast(new SimpleChannelInboundHandler<WebSocketFrame>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
// 仅仅出力文本消息处理
if (msg instanceof TextWebSocketFrame) {
String request = ((TextWebSocketFrame) msg).text();
System.out.println("服收到消息:" + request);
// 转换为大写后,写回
ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));
}
Attribute<Integer> attribute = ctx.channel().attr(count);
Integer val = attribute.get();
if (val == null) {
attribute.set(1);
} else {
if (val >= 10) {
// 发送 bye 消息到客户端,由客户端主动关闭channel
ctx.channel().writeAndFlush(new TextWebSocketFrame("bye"));
} else {
attribute.compareAndSet(val, val + 1);
}
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("已经断开与客户端的channel");
super.channelInactive(ctx);
};
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if(evt instanceof HandshakeComplete) {
HandshakeComplete handshakeComplete = (HandshakeComplete) evt;
String uri = handshakeComplete.requestUri();
HttpHeaders httpHeaders = handshakeComplete.requestHeaders();
String selectedSubprotocol = handshakeComplete.selectedSubprotocol();
System.out.println("ws握手:uri=" + uri + ",headers=" + httpHeaders + ",subPortocol=" + selectedSubprotocol);
}
super.userEventTriggered(ctx, evt);
}
});
}
});
Channel channel = serverBootstrap.bind(1024).sync().channel();
channel.closeFuture().sync();
} finally {
bossEventLoopGroup.shutdownGracefully();
workerEventLoopGroup.shutdownGracefully();
}
}
}
结果
客户端输出日志
收到服务器消息:HELLO: 1584259504015,是否是最后一帧:true
收到服务器消息:HELLO: 1584259505018,是否是最后一帧:true
收到服务器消息:HELLO: 1584259506018,是否是最后一帧:true
收到服务器消息:HELLO: 1584259507018,是否是最后一帧:true
收到服务器消息:HELLO: 1584259508018,是否是最后一帧:true
收到服务器消息:HELLO: 1584259509019,是否是最后一帧:true
收到服务器消息:HELLO: 1584259510020,是否是最后一帧:true
收到服务器消息:HELLO: 1584259511021,是否是最后一帧:true
收到服务器消息:HELLO: 1584259512022,是否是最后一帧:true
收到服务器消息:HELLO: 1584259513022,是否是最后一帧:true
收到服务器消息:HELLO: 1584259514023,是否是最后一帧:true
收到服务器消息:bye,是否是最后一帧:true
已经关闭和服务端的channel
服务端输出日志
ws握手:uri=/channel,headers=DefaultHttpHeaders[Connection: Upgrade, Content-Length: 0, Host: localhost:1024, Upgrade: websocket, User-Agent: Java-http-client/13.0.2, Sec-WebSocket-Key: HE3IjKqJTR72L2CpgyiVIg==, Sec-WebSocket-Version: 13],subPortocol=null
服收到消息:Hello: 1584259504015
服收到消息:Hello: 1584259505018
服收到消息:Hello: 1584259506018
服收到消息:Hello: 1584259507018
服收到消息:Hello: 1584259508018
服收到消息:Hello: 1584259509019
服收到消息:Hello: 1584259510020
服收到消息:Hello: 1584259511021
服收到消息:Hello: 1584259512022
服收到消息:Hello: 1584259513022
服收到消息:Hello: 1584259514023
已经断开与客户端的channel
AG 百家家乐正规网址《 787977.tv 飞机 @gb560 》一路走到 java 工程师,java 都快出 java9 了,到底该如何学 java?
期望本文能给一些在职想转行或许在校想学习 Java 的同学们一些小的启示。
如果我的文章能有幸被你看到,那么很大可能你和我一样,是半路出家的转行人员,不论有没有根底,相关于那些科班出身的同学来说,我们真的不知道从哪开端,在我从零开端 自学到现在现已做 Javaweb 快两年了,有了一些自己的小感悟,写出来和我们分享,也期望能有一些技术大牛能给我们这些非科班的同学一些好的主张。

废话少说,否则就文不对题了,那么转行 Java 的入门作业有哪些呢?以下是我的个人经历,仅供参阅,我们如果看了必定要结合自身需求,否则被我带翻车了我可负不起这个责任啊。
1、我觉得转行的同学由于根底和专业布景的原因,一般进入大公司的可能性较低,更多的可能挑选一些小的私企,那里面的作业嘛,肯定是前端后台自个都得一把抓咯,那已然是这样,我们是不是能够先从简略的开端呢,比方 HTML 和 CSS,花个一天的时刻学习一下根底视频,然后自己仿照着做一个页面,一天就能做个页面,是不是很有成就感。

2、Java 考究的就是全部皆目标的编程思维,已然我们现已学习过了 HTML 和 CSS,谈到面向目标,我们当然应该学习下 javascript 了,尽管 javascript 和 Java 是两种彻底不同的编程言语,可是它有助于我们树立面向目标的思维,而且根底的东西简略易学,简略上手,当然就成为我们通往 Java 的首选了。

3、学习自身就是一个与忘记做奋斗的进程,我们对自己的要求做到有个形象,要用的时分能够百度到就 OK 了,学了上面的内容是不是觉得学习编程也没有那么难嘛,而且现在公司敲代码的初级程序员的许多作业都是基于框架的 copy&paste,当然咯,话虽如此说,不过该学的却是一个都不能少,现在我们就能够大刀阔虎的进入 Java 的学习了。

4、网络上有着各式各样的 Java 根底视频,“Java - 从入门到抛弃”,“Java,21 天从看懂到看开”,“Java - 从入行到改行”,各种视频良莠不齐,那些什么 Java 的编程圣经 —— Java 编程思维 ,前期如同不是很有必要去触摸。
5、在看 Java 根底视频的时分,必定要一边看一遍跟着做,否则你花再多的时刻也搞不明白什么是封装、继承、笼统、多态等等笼统的概念,而且只要代码量堆集到必定程度了,许多 jdk 里面的 api 才会手到擒来,不需求每次都去百度。
============= 完毕 Java se 根底的学习 ==============================

6、当我们把 java 根底视频认仔细看了一道两遍,而且仔细跟着敲了必定量额代码了,而且根本上会使用一种编译器了(eclipse 或许 IDEA 等,引荐 idea),我们就能够更深一步的去做 Javaweb 方面的工作了,逆向学习,先在网上找几篇不错的博客,装置好 javaweb 运转需求的环境,比方 tomcat,maven,mysql 数据库等,然后跟着网络教程新建一个 ssm(spring+springmvc+mybatis 或许 ssh)的项目,运转起来,当你看到页面上主动跳转出 Hello World 的时分,相信你必定会为你以上一切的尽力而自豪。

7、尽管最根底的 javaweb 项目跑起来了,但这并不代表我们就学会使用了,现在我们应该买一本 javaweb 的从零入门的参阅书本,好好学习里面的 servlet,jsp,cookie,session,encoding 和 spring,springmvc 等等常识,当然这是一个十分绵长的进程,需求很多的堆集和实践操作,我们也能够多在慕课网上找一些琐细的小视频看看各个模块的介绍和简略使用,经过不断的学习和实践来了解和稳固我们的常识。

8、当我们能对 Javaweb 有一个大约的了解了之后,知道各个模块在开发中的效果和为什么要使用它们的时分,我们需求学习一下 sql 和 mysql 了,关于怎样优化功能这种巨大上的常识我们先抛开不谈,能搞装置 mysql 并设置密码,能够新建数据库插入表,经过 sql 进行简略的 crud,进行相关查询,知道主键,不为空(not null),sql 的各种数据类型,索引和外键的效果,到这儿应该就够用了。

9、到这一步就能够测验去网上找一些完好的项目视频,从需求剖析,到设计文档,从程序开发,到项目测验,一行一行,一字一句,认仔细真过几遍,不能说闭上眼睛你能彻底记住,但至少不能闭上眼睛就是天亮吧,能够大致知道一个流程,而且能知道每个流程是干嘛的,就够了。

10、到此为止,javaweb 最最根底的东西我们根本都现已掌握了,许多东西我在描述的时分都是做了最低要求 —— 差不多就行。为什么这么说了,由于 javaweb 的常识真的算是海量,短时刻内想保质保量的全学会难度太大,我们能够先学会怎样用,再去学习怎样用的更好,在真实的项目中,查漏补缺,完善自己。
刚开端学习编程最大的难点在于,我压根不知掉我学的这些东西怎样用,怎样经过这些东西就能做出一个网页,一个游戏呢,好烦躁,我每天都是敲的最最简略的算法,复杂点的全在控制台就给我输出了,离我的黑客梦八竿子打不到一块,我的天,这些东西用编程言语完成还不如我自个儿拿张纸了随意画画呢,烦躁了是不是,别急啊各位同学,学完根底后你离项目只要一步之遥了,那就是嘿嘿 —— 持续前行。 时刻过的很快,转眼间曾经学的东西就忘得差不多了,我好慌
docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)
上一篇
本篇介绍如何使用docker创建Java容器运行SpringBoot项目
大部分教程都是使用Dockerfile来创建镜像再去运行,当然这也是一种办法,本篇两种方法都有介绍:
思路1:先拉取java镜像,构建java容器,再把SpringBoot的jar包拷进容器,然后进入容器运行jar包就OK了。
思路2:构建DockerFile创建SpringBoot容器运行。
实现方式一
①、拉取镜像
docker pull java:8
②、运行容器
docker run -p 8888:8001 --name java-test -d java:8 tail -f /dev/null
参数解释:
-p | 端口映射:(主机端口:容器端口) |
--name | 容器名称(java-test) |
-d | 后台运行 |
java:8 | 镜像名称:版本号 |
tail -f /dev/null | 有事可做(不然运行了就退出了) |
③、拷贝 jar 包到容器内部
1、先下载SpringBoot项目jar包
jar包下载地址:https://gitee.com/cnetopro/springboot-dcoker
2、通过Xftp或者其他软件把 springboot-0.0.1-SNAPSHOT.jar 传输到主机
3、把 springboot-0.0.1-SNAPSHOT.jar 拷贝到容器内部
docker cp /root/springboot-0.0.1-SNAPSHOT.jar 容器ID:/
④、进入容器运行项目
进入容器
docker exec -it 容器ID bash
运行SpringBoot项目
nohup java -jar springboot-0.0.1-SNAPSHOT.jar /dev/null 2>&1 &
参数解释:
buhup | 谐音no hope,用于后台运行退出不终止项目。 |
dev/null | 日志输入地址(不保留日志) |
2>&1 & | 标准输出 |
查看运行情况
ps -aux|grep java
⑤万事大吉
在浏览器输入 IP:8888 即可看到:
Hello SpringBoot Docker
实现方式二
使用Dockerfile构建SpringBoot项目运行环境
①、拉取镜像
docker pull java:8
②、下载 SpringBoot 项目 jar 包
1、先下载SpringBoot项目jar包
jar包下载地址:https://gitee.com/cnetopro/springboot-dcoker
2、通过Xftp或者其他软件把 springboot-0.0.1-SNAPSHOT.jar 传输到主机
③、创建Dockerfile
vim Dockerfile
内容:
FROM java:8 copY springboot-0.0.1-SNAPSHOT.jar / CMD java -jar springboot-0.0.1-SNAPSHOT.jar
解释:
FROM | 基于 java:8镜像创建 |
copY | 把当前目录的springboot-0.0.1-SNAPSHOT.jar拷贝到容器内的/目录下 |
CMD | 执行命令java -jar springboot-0.0.1-SNAPSHOT.jar 运行项目 |
④、构建镜像
docker build -t springboot_test .
解释:
build -t |
构建镜像名为 springboot_test |
. | 表示当前目录的Dockerflie文件 |
⑤、运行镜像
docker run -p 8888:8001 --name java-test -d springboot_test
⑥、万事大吉
在浏览器输入 IP:8888 即可看到:
Hello SpringBoot Docker
今天关于java9 系列 (二) docker 运行 java9和docker运行java程序的介绍到此结束,谢谢您的阅读,有关5分钟学会Java9-Java11的七大新特性、5分钟学会Java9的WebSocket 客户端api、AG 百家家乐正规网址《 787977.tv 飞机 @gb560 》一路走到 java 工程师,java 都快出 java9 了,到底该如何学 java?、docker 使用教程4-(Docker创建Java容器运行SpringBoot项目)等更多相关知识的信息可以在本站进行查询。
本文标签: