1. 程式人生 > >基於Spring Boot的微服務搭建

基於Spring Boot的微服務搭建

dep array bin ans interface ide conn 重要 instance

環境:

技術分享圖片

項目結構:

技術分享圖片

關鍵配置

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的微服務搭建