Docker中部署Spring Boot应用程序!


在每个生命周期阶段,我们都在使用多种语言,框架,体系结构来开发应用程序,这会带来极大的复杂性。有一种进行基于容器的部署的冲动。Spring Boot和Docker一起是开发RESTful Web服务应用程序的绝佳组合。在本文中,我将尝试解释:

  • Docker及其优势。 创建一个Spring Boot应用程序。在Docker中托管Spring Boot应用程序。

Docker Docker是一种开源技术,主要用于开发,交付和运行应用程序。Docker的出色之处在于,一旦将应用程序及其所有依赖项打包到Docker容器中,就确保它可以在任何环境中运行。Docker容器映像是轻量级的,独立的,可执行的软件软件包,其中包含运行应用程序所需的一切。例如,创建Java应用程序需要Java库,并且在将其部署到任何系统或VM上时,需要首先安装Java。但是,在一个容器中,所有东西都保持在一起并作为一个包运输,例如在Docker容器中。阅读文档以获取有关Docker容器的更多信息。

Spring Boot应用程序 Spring Boot是一个基于微服务的框架,因此只需很少的时间就可以制作可用于生产的应用程序。开发人员可以自动配置其Spring应用程序。但是,Spring Boot也能够根据您列出的依赖项来更改配置。例如,当您将“ MySQL”列为依赖项时,它将使用包括的“ MySQL连接器”来配置Spring应用程序。无需将您的应用程序部署到Web服务器。您只需输入run命令即可启动应用程序。让我们看看如何创建一个示例Spring Boot应用程序。

打开Spring Starter以使用Spring Starter库创建Java Maven应用程序。

screenshot-2020-05-08-at-001346.png

提供工件组和名称,并在依赖项中添加“ Web”,并将其他所有内容保留为默认值,这将使用Java和Spring Boot创建一个Maven项目。这将生成一个ZIP文件,该ZIP文件将作为Maven项目导入到IDE中。

screenshot-2020-05-08-at-001945.png

就这些!。导入应用程序后,创建一个示例端点来检查应用程序的功能。

screenshot-2020-05-08-at-002554.png

在运行应用程序并访问浏览器中的端点后,您将能够看到如下结果:

screenshot-2020-05-08-at-002920.png

项目结构将如下所示:

screenshot-2020-05-08-at-003331.png

所有文件的简要概述:

  • ApplianceController:包含所有其余端点的业务逻辑。
  • ApplianceRepository:负责在数据库表上提供CRUD操作。
  • ApplianceEntity:指定该类是一个实体,并映射到数据库表。
  • pom.xml: 包含应用程序所需的所有依赖项。
  • application.properties:用于配置Web属性和数据库配置。
  • Dockerfile:Docker使用户能够创建自己的Docker映像并将其部署在Docker中。要创建自己的Docker映像,我们必须创建自己的Dockerfile。基本上,Dockerfile是一个简单的文本文件,其中包含构建映像所需的所有说明
  • docker-compose.yml:指定应部署的服务/容器,并定义如何构建容器的映像。
  • schema.sql: 包含执行数据库操作的脚本。 让我们逐一讲解每个课程:

HouseHoldApplication 这是一个Spring Boot主类。Spring Boot REST应用程序通过此类加载。我们还可以看到该类是使用注解@SpringBootApplication创建的。按照Spring文档,注释@SpringBootApplication相当于用@Configuration,@EnableAutoConfiguration和@ComponentScan,这些注解经常一起使用。在大多数情况下,在Spring Boot开发中,总是使用这三个重要的注释对主类进行注释。

并且我们将使用组件路径来修改@SpringBootApplication(在Java类中提供如下)。否则,应用程序将无法找到控制器类。

package com.user.household;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityListeners;

@SpringBootApplication
@EnableTransactionManagement
@EnableCaching
@ComponentScan(basePackages = {"com.user"})
@EntityScan("com.user.model")
@EnableJpaRepositories("com.user.repository")
public class HouseHoldApplication {

    public static void main(String[] args) {

        SpringApplication.run(HouseHoldApplication.class, args);
    }

}

ApplianceController 此类负责创建应用程序必需的RESTful端点,并在单独定义的存储库的帮助下访问数据库。的@RequestMapping注解默认映射所有HTTP操作,并且在本申请中,它确保HTTP请求/家电/映射到getAllAppliances()方法。完成GET调用后,我们需要使用相同的路径实现RESTful POST调用。

POST调用使用户可以在数据库中创建设备或条目。同样,我们需要为更新,搜索和删除操作实现RESTful服务。

import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController
@RequestMapping("/appliances")
public class ApplianceController {

    @Autowired
    private ApplianceRepository repository;

    /**
     * Get the entire list of appliances
     **/

    @GetMapping("/")
    public List<ApplianceEntity> getAllAppliances() {

        return repository.findAll();

    }

    /**
     * Create a new appliance

     **/

    @PostMapping("/")
    public ApplianceEntity createAppliance(@Valid @RequestBody ApplianceEntity appliance) throws RecordWithSameModelException, RecordWithSameBrandException {

        return repository.save(appliance);

    }

ApplianceEntity 这是设备实体。每个实体必须至少定义两个注释:@Entity和@Id。的@Entity注释指定的类是一个实体,并且被映射到数据库表中。该@Table 用于映射批注指定数据库表的名称。的@Id注释指定的实体的主密钥和@GeneratedValue提供的主键的值生成策略的规范。

package com.user.model;

import javax.persistence.*;
import java.time.LocalDate;
import java.util.Date;

@Entity
@Table(name="HOUSEHOLD")
public class ApplianceEntity {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer serialnumber;

    @Column(name="brand")

    private String brand;

    @Column(name="model")
    private String model;

    @Column(name="status")
    private String status;

    @Column(name="date")
    private LocalDate date;

    public ApplianceEntity() {
    }

    public ApplianceEntity(Integer id, String brand, String model, String status,LocalDate date) {
        super();

       this.serialnumber = id;
        this.brand = brand;

        this.model = model;
        this.status = status;
        this.date=date;
    }

    public Integer getSerialnumber() {
        return serialnumber;
    }

    public void setSerialnumber(Integer serialnumber) {
        this.serialnumber = serialnumber;
    }

    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {

        this.brand = brand;

    }

    public String getModel() {
        return model;

    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

ApplianceRepository @Repository批注用于定义存储库。

package com.user.repository;

import com.user.model.ApplianceEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.*;

import java.awt.print.Pageable;

@Repository
public interface ApplianceRepository extends JpaRepository<ApplianceEntity,Long>,JpaSpecificationExecutor<ApplianceEntity>{

}

schema.sql 该文件负责创建数据库条目。

DROP TABLE IF EXISTS HOUSEHOLD;

CREATE TABLE HOUSEHOLD(
SERIALNUMBER SERIAL PRIMARY KEY NOT NULL,
BRAND VARCHAR(30) NOT NULL,
MODEL VARCHAR(30) NOT NULL,
STATUS VARCHAR(30) NOT NULL,
DATE DATE DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('samsung','S100','active',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('samsung','S200','active',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('LG','L100','inactive',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('HITACHI','H100','active',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('samsung','S900','inactive',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('sony','SS100','active',NOW());
INSERT INTO HOUSEHOLD(BRAND,MODEL,STATUS,DATE) VALUES('OGENERAL','O100','active',NOW());

编写了所有业务逻辑并定义了端点之后,我们需要按照以下步骤创建应用程序的JAR。

  • mvn全新安装
  • mvn清洁包装 结果,创建了一个JAR,如下所示:

screenshot-2020-05-08-at-012801.png

创建JAR后,我们需要通过定义以下文件对应用程序进行Docker化:

Dockerfile

  • FROM openjdk:8表示这是一个Java应用程序,将需要所有Java库。因此,它将拉出所有与Java相关的库,并将它们添加到容器中。
  • COPY 复制应用程序生成的JAR,并将其添加到容器中。
  • CMD表示这是一个JAR,我们需要从Docker内部运行此JAR。
FROM openjdk:8-jdk-alpine
COPY target/household-0.0.1-SNAPSHOT.jar /app/app.jar
CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]

docker-compose.yml

  • 它包含关键字postgres和web,它们定义了针对应用程序的web和数据库部分的服务。
  • 该图像关键字用于从指定图像dockerhub我们的Postgres和Web容器
  • 对于数据库,我们使用ports关键字来提及postgres需要公开的端口。
  • 最后,我们需要为postgres指定环境变量,这是运行postgres所必需的。
version: '3.2'
services:
  postgres:
    restart: always
    container_name: sample_db
    image: postgres:10.4
    ports:
      - '5432:5432'
    environment:
         - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
         - POSTGRES_USER=${POSTGRES_USER}
         - POSTGRES_DB=${POSTGRES_DB}
# APP**
  web:

    build: .

    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/test
    expose:
      - '8080'
    ports:
      - '8080:8080'

现在,我们进入了以下阶段:

  1. Java – Spring Boot应用程序
  2. 将创建要在Docker容器中运行的映像的Dockerfile。

要将它们加载到Docker容器中,我们必须首先创建映像,然后从Docker容器中运行该映像。我们需要在包含Dockerfile的文件夹中运行某些命令。

这将在Docker中创建我们的映像并将其加载到容器中。

screenshot-2020-05-08-at-014809.png

我们已经成功构建了可以按如下方式运行的映像:

screenshot-2020-05-08-at-015302.png

太好了 Spring Boot应用程序已启动,服务器在端口8080上运行。

screenshot-2020-05-08-at-015454.png

Spring Boot Application正在Docker容器中运行。


原文链接:http://codingdict.com