基于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 {}