基于Spring Boot的微服务搭建

Posted xinglichao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Spring Boot的微服务搭建相关的知识,希望对你有一定的参考价值。

环境:

项目结构:

关键配置

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xlc</groupId>
    <artifactId>demohmm</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demohmm</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

 

application.yml

spring:
  datasource:
     driver-class-name: com.mysql.jdbc.Driver
     url: jdbc:mysql:///parameter?useSSL=false
     username: root
     password: 123456
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

 

 

Table1.java

package com.xlc.hmm;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

import org.hibernate.annotations.Proxy;

@Entity
@Proxy(lazy = false)
public class Table1 {
    
    @Id
    @Column(name="id")
    private int id;
    @Column(name="wordlist")
    private String wordList;
    @Column(name="labellist")
    private String labelList;
    @Column(name="wordsize")
    private int wordSize;
    @Column(name="labelsize")
    private int labelSize;
    @Column(name="pi")
    private String pi;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getWordList() {
        return wordList;
    }
    public void setWordList(String wordList) {
        this.wordList = wordList;
    }
    public String getLabelList() {
        return labelList;
    }
    public void setLabelList(String labelList) {
        this.labelList = labelList;
    }
    public int getWordSize() {
        return wordSize;
    }
    public void setWordSize(int wordSize) {
        this.wordSize = wordSize;
    }
    public int getLabelSize() {
        return labelSize;
    }
    public void setLabelSize(int labelSize) {
        this.labelSize = labelSize;
    }
    public String getPi() {
        return pi;
    }
    public void setPi(String pi) {
        this.pi = pi;
    }
    @Override
    public String toString() {
        return "Table1 [id=" + id + ", wordList=" + wordList + ", labelList=" + labelList + ", wordSize=" + wordSize
                + ", labelSize=" + labelSize + ", pi=" + pi + "]";
    }

}

 

Table2、Table3同理基于数据库映射关系构建

Table1Respository.java

package com.xlc.hmm;

import org.springframework.data.jpa.repository.JpaRepository;
                                                                 //此处可以指定其他类型,因需而定
public interface Table1Respository extends JpaRepository<Table1, Integer>{}

 

Table2Respository.java、Table2Respository.java同理

HmmController.java

package com.xlc.hmm;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

//@Component
//@Order(value=1)
//class StartUpRunner implements CommandLineRunner {  
//    @Override 
//    public void run(String... args) throws Exception {
////        new ParamFromSql();
//        System.out.println("SUCCESS");
//    }  
//}

@Component
class ParamFromSql {
    
    @Autowired
    private Table1Respository table1Respository;
    
    @Autowired
    private Table2Respository table2Respository;
    
    @Autowired
    private Table3Respository table3Respository;
    
    public static ParamFromSql paramFromSql;
    
    static List<String> wordlist;
    static List<String> labellist;
    static double[] pi;
    static double[][] A;
    static double[][] B;

    @PostConstruct
    public void init() {
        
        paramFromSql = this;
        paramFromSql.table1Respository = this.table1Respository;
        paramFromSql.table2Respository = this.table2Respository;
        paramFromSql.table3Respository = this.table3Respository;
        
        wordlist = new ArrayList<String>();
        labellist = new ArrayList<String>();
//        getParamFromMysql();
//        Table1 table1 = paramFromSql.table1Respository.getOne(1);
//        paramFromSql.table1Respository.getOne(1);
//        System.out.println(paramFromSql.table1Respository.getOne(1));
        Table1 table1 = paramFromSql.table1Respository.getOne(1);
        System.out.println(table1.getLabelList());
        labellist = Arrays.asList(table1.getLabelList().split(" "));
        wordlist = Arrays.asList(table1.getWordList().split(" "));
        String[] piStr = table1.getPi().split(" ");
        int labelSize= table1.getLabelSize();
        int wordSize = table1.getWordSize();
        pi = new double[labelSize];
        A = new double[labelSize][labelSize];
        B = new double[labelSize][wordSize];
        
        int j = 1;
        for (int i = 0; i < labelSize; ++i) {
            pi[i] = Double.valueOf(piStr[i]);
            
            String[] rowAStrs = paramFromSql.table2Respository.getOne(j).getRowA().split(" ");
            for(int k = 0; k < labelSize; ++k) {
                A[i][k] = Double.valueOf(rowAStrs[k]);
            }
            
            String[] rowBStrs = paramFromSql.table3Respository.getOne(j).getRowB().split(" ");
            for(int k = 0; k < wordSize; ++k) {
                B[i][k] = Double.valueOf(rowBStrs[k]);
            }
            
            ++j;
            
        }
        
        System.out.println("SUCCESS");
    }
    
}

class Test{
    public void test() {
        System.out.println("-------------------------");
        System.out.println(ParamFromSql.A[0][0]);
        System.out.println(ParamFromSql.B[0][0]);
        System.out.println("-------------------------");
    }
}


class SetLabel{

    public String setLabel(String strInput) {
        String result = "";
        try {
            int[] labelindex = viterbi(strInput, ParamFromSql.pi, ParamFromSql.A, ParamFromSql.B);
            String[] strwords = strInput.split(" ");
            for (int i = 0; i < labelindex.length; i++) {
                result += strwords[i] + "/" + ParamFromSql.labellist.get(labelindex[i]) + " ";
                
            }    
        }catch(Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    // viterbi
    public int[] viterbi(String string, double[] pi, double[][] A, double[][] B) throws IOException{
        
        
        String[] words = string.split(" ");
        double[][] delta = new double[words.length][pi.length];
        int[][] way = new int[words.length][pi.length];
        int[] labelindex = new int[words.length];
        //System.out.println(words[0]);
        for (int i = 0; i < pi.length; i++) {
            delta[0][i] = pi[i] * B[i][ParamFromSql.wordlist.indexOf(words[0])];  //////////////////////////////////////////////
        }
        for (int t = 1; t < words.length; t++) {
            //System.out.println(words[t]);
            for (int i = 0; i < pi.length; i++) {
                for (int j = 0; j < pi.length; j++) {
                    ////////
                    //System.out.println("t:" +t + "i:" + i + "j:" + j + "wordlist.indexOf(words[t]):"
                        //    + wordlist.indexOf(words[t]));
                    if(delta[t][i] < delta[t-1][j] * A[j][i] * B[i][ParamFromSql.wordlist.indexOf(words[t])]) {
                        delta[t][i] = delta[t-1][j] * A[j][i] * B[i][ParamFromSql.wordlist.indexOf(words[t])];
                        way[t][i] = j;
                    }
                }
            }
        }
        double max = delta[words.length - 1][0];
        labelindex[words.length - 1] = 0;
        for (int i = 0; i < pi.length; i++) {
            if (delta[words.length - 1][i] > max) {
                max = delta[words.length - 1][i];
                labelindex[words.length - 1] = i;
            }
        }
        for (int t = words.length - 2; t >= 0; t--) {
            labelindex[t] = way[t + 1][labelindex[t + 1]];
        }
        //System.out.println(Arrays.toString(labelindex));
        return labelindex;
    }
    
}

@RestController
public class HmmController {
        
    
    public String justDoIt(String str) {
        String resultStr = null;
        try {
            resultStr =  new SetLabel().setLabel(str);
        }catch(Exception e) {
            e.printStackTrace();
        }
        
        return resultStr;
    }

    @PostMapping("/hmm")
    public String hmmDemo(@RequestParam(value = "str", required = false, defaultValue = "0") String testStr) {//        return testStr;
        if(testStr.equals("0")) {
            return "are you kidding me?";
        }else {
            return justDoIt(testStr);
        }
        
    }
    
    @GetMapping("/test")
    public String test() {
//        new Test().test();
        return "do you like me?";
    }

}

 

DemohmmApplication.java

package com.xlc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemohmmApplication {

    public static void main(String... args) {
                
        SpringApplication.run(DemohmmApplication.class, args);
    }
}

 

现在右键DemohmmApplication运行,启动项目

看见这个是不是很激动

  .   ____          _            __ _ _
 /\\\\ / ___\'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\
( ( )\\___ | \'_ | \'_| | \'_ \\/ _` | \\ \\ \\ \\
 \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  \'  |____| .__|_| |_|_| |_\\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)

 

现在来使用Postman测试一下

  • 简单Get请求

  • 微服务测试(通过Post请求传入参数)

其实整个项目结构还是很清晰的

对于很多注解的使用,就需要好好的看书或着通过其他途径来学习一下了

这里再详细说明一下遇到的一个问题:在启动服务的时候将必要的模型参数读入内存以便在服务使用时可以很快的给出结果,而不是每请求一次就去数据库中读取一次参数,这样是耗时且不明智的

于是就使用到了@Component,被注解的类在项目启动时会进行加载,在这个类中可以定义

@Autowired
private Table1Respository table1Respository;

 

而不会在后续读库时报空指针异常

具体的用法就是

@Component
class ParamFromSql {
    
    @Autowired
    private Table1Respository table1Respository;
    
    public static ParamFromSql paramFromSql;

    @PostConstruct
    public void init() {
        
        paramFromSql = this;
        paramFromSql.table1Respository = this.table1Respository;
    }
}

 

想要获取操作数据库就使用 paramFromSql.table1Respository.具体的方法

还有一个重要的问题就是Hibernate默认的Lazy模式导致的no session异常

此时一个简单粗暴的解决办法就是在实体类上加注解指明不适用Lazy

@Entity
@Proxy(lazy = false)
public class Table1 {}

 

 


 Github:https://github.com/xinglicha0/SpringBoot-Hmm

以上是关于基于Spring Boot的微服务搭建的主要内容,如果未能解决你的问题,请参考以下文章

基于Spring Cloud的微服务构建学习-2 Spring Boot

基于 Spring Boot 的微服务集成测试

在 spring boot 基于 webflux 的微服务中,订阅者是谁?

Spring Cloud+Spring Boot 自学01

spring boot 怎么启动

spring boot 使用脚本启动.bat怎么写