Spring-Boot -- Google Protocol Buffer的应用


上一篇: Google Protocol Buffer -- Windows下Python的应用

    

       在上一篇博文中我罗略了一些关于Protobuf的资料,以及其在Python下的应用,因为protobuf协议是跨语言平台的,所以本篇基于Java语言下的应用和Python的如出一辙,就不再讲如何安装protobuf和编写proto文件了,本篇从另一个角度解答为什么使用protobuf协议传输通信要比使用xml和json的效率高的多。



一、项目目录结构








二、Pom


<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.appleyk</groupId>
  <artifactId>Spring-Boot-Protocol-Buffer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <description>Spring-Boot -- Google Protobuff的应用</description>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.12.RELEASE</version>
	</parent>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 添加热部署 devtools:监听文件变动 -->
		<!-- 当Java文件改动时,Spring-boo会快速重新启动 -->
		<!-- 最简单的测试,就是随便找一个文件Ctrl+S一下,就可以看到效果 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<!-- optional=true,依赖不会传递 -->
			<!-- 本项目依赖devtools;若依赖本项目的其他项目想要使用devtools,需要重新引入 -->
			<optional>true</optional>
		</dependency>
		<!-- Spring 单元测试 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- JUnit单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.protobuf</groupId>
			<artifactId>protobuf-java</artifactId>
			<version>3.5.0</version>
		</dependency>	
	</dependencies>
</project>





三、Student实体类


package com.appleyk.protocol.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 学生类
 * @author yukun24@126.com
 * @blob   http://blog.youkuaiyun.com/appleyk
 * @date   2018年6月13日-下午3:00:33
 */
public class Student {

	/**
	 *  ID == 唯一标识
	 */
	private Long id;
	
	/**
	 *  姓名
	 */
	private String name;
	
	/**
	 *  兴趣爱好
	 */
	private List<String> hobbies;
	
	/**
	 * 各科成绩
	 */
	private Map<String, Double> grades;
	
	public Student(){
		hobbies = new ArrayList<>();
		grades = new HashMap<>();
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<String> getHobbies() {
		return hobbies;
	}

	public void setHobbies(List<String> hobbies) {
		this.hobbies = hobbies;
	}

	public Map<String, Double> getGrades() {
		return grades;
	}

	public void setGrades(Map<String, Double> grades) {
		this.grades = grades;
	}
	
	public void addHobby(String hobby){
		hobbies.add(hobby);
	}
}




四、Proto协议文件


Student.proto


syntax = "proto3";//这个版本的protoc的protobuf编译器已经可以支持proto2语法和proto3的语法
package com.appleyk.protocol.model; 
option java_outer_classname = "SObjectModel";  //输出的类名

message Students{
	
	repeated Student students = 1;
	
	message Student{
	
		int64 id    = 1 ;
		string name = 2 ;
		repeated string hobbies   = 3 ;
		map<string,double> grades = 4 ;
	
	}

}
  






五、基于demo实现CMD命令行的protoc的编译指令





package com.appleyk.protocol.utils;

import java.io.IOException;

/**
 * protoc.exe -I=proto的输入目录 --java_out=java类输出目录 proto的输入目录包括包括proto文件
 * 
 * @author Administrator
 *
 */

public class GenerateClass {
	public static void main(String[] args) throws IOException {

		String protoFile = "Student.proto";
		String path = "E:/Spring-boot/Spring-Boot-Protocol-Buffer/src/main/java/com/appleyk/protocol/proto";
		String out = "E:/Spring-boot/Spring-Boot-Protocol-Buffer/src/main/java";
		String strCmd = "D:/protobuf/src/protoc.exe -I=" + path + " --java_out=" + out + " " + path + "/" + protoFile;
		System.out.println(strCmd);
		Runtime.getRuntime().exec(strCmd);
		System.out.println("完成");

	}
}






六、编译Student.proto







编译后,刷新项目,会在model包下多出一个类文件





此文件就是基于proto文件协议编译后的Java类




七、测试SObjectModel类





package com.appleyk.protocol.test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.appleyk.protocol.model.SObjectModel.Students;
import com.appleyk.protocol.model.SObjectModel.Students.Student;
import com.fasterxml.jackson.databind.ObjectMapper;

public class StudentModelTest {

	
	public static void main(String[] args) throws Exception{
		
		/**
		 *  消息体的构建器,消息体的build方法可以产生对象
		 */
		Students.Builder sBuilders = Students.newBuilder();
		
		Student.Builder sBuilder = Student.newBuilder();	
		sBuilder.setId(1001L);
		sBuilder.setName("张三");
		//添加兴趣爱好
		sBuilder.addHobbies("游戏");
		sBuilder.addHobbies("睡觉");
		sBuilder.addHobbies("篮球");
		
		//添加成绩键值对
		sBuilder.putGrades("数学", 95.5);
		sBuilder.putGrades("语文", 88.5);
		sBuilder.putGrades("英语", 99.0);
		
		
		Student.Builder sBuilder2 = Student.newBuilder();	
		sBuilder2.setId(1002L);
		sBuilder2.setName("李玟");
		//添加兴趣爱好
		sBuilder2.addHobbies("逛街");
		sBuilder2.addHobbies("看书");
		
		//添加成绩键值对
		sBuilder2.putGrades("数学", 85.5);
		sBuilder2.putGrades("语文", 92.0);
		sBuilder2.putGrades("英语", 95.5);
		
		//学生列表构建  == 添加两个学生builder【消息体】
		sBuilders.addStudents(sBuilder);
		sBuilders.addStudents(sBuilder2);
		
		//builder 转 对象
		Students students = sBuilders.build();
		System.out.println("输出对象信息:"+students);
		byte[] data = students.toByteArray();
		System.out.println("protobuff字节数:"+data.length);
				
		//对象 再次转化成Java实体类
		pbfModelToJavaEntity(students.getStudentsList());
		
	}	
	
	
	public static void pbfModelToJavaEntity(List<Student> students) throws Exception{
		
		List<com.appleyk.protocol.entity.Student> stuList = new ArrayList<>();
		com.appleyk.protocol.entity.Student stu;
		for (Student student : students) {
			stu = new com.appleyk.protocol.entity.Student();
			stu.setName(student.getName());
			stu.setId(student.getId());
			
			//取兴趣爱好
			for(int i =0;i<student.getHobbiesCount();i++){
				stu.addHobby(student.getHobbies(i));
			}
			
			//取各科成绩
			Map<String, Double> gradesMap = student.getGradesMap();
			stu.setGrades(gradesMap);
			stuList.add(stu);
		}
		ObjectMapper mapper = new ObjectMapper();
		String json  = mapper.writeValueAsString(stuList);
		System.out.println("json字节数:"+json.getBytes().length);
	}
}



运行结果:


输出对象信息:students {
  id: 1001
  name: "\345\274\240\344\270\211"
  hobbies: "\346\270\270\346\210\217"
  hobbies: "\347\235\241\350\247\211"
  hobbies: "\347\257\256\347\220\203"
  grades {
    key: "\346\225\260\345\255\246"
    value: 95.5
  }
  grades {
    key: "\350\257\255\346\226\207"
    value: 88.5
  }
  grades {
    key: "\350\213\261\350\257\255"
    value: 99.0
  }
}
students {
  id: 1002
  name: "\346\235\216\347\216\237"
  hobbies: "\351\200\233\350\241\227"
  hobbies: "\347\234\213\344\271\246"
  grades {
    key: "\346\225\260\345\255\246"
    value: 85.5
  }
  grades {
    key: "\350\257\255\346\226\207"
    value: 92.0
  }
  grades {
    key: "\350\213\261\350\257\255"
    value: 95.5
  }
}

protobuff字节数:180
json字节数:232


我们可以很清楚的看到,使用proto协议文件构建的对象体要比同信息同内容的Java实体对象【json格式】包含的字节数要少,随之而来的就是传输效率要高了。




八、项目GitHub地址





"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:D:\IDEA\IntelliJ IDEA 2023.2.8\lib\idea_rt.jar=58609:D:\IDEA\IntelliJ IDEA 2023.2.8\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;D:\ChromeCoreDownloads\wvp-GB28181-pro-master (1)\wvp-GB28181-pro-master\target\classes;D:\repository\org\springframework\boot\spring-boot-starter-data-redis\2.7.18\spring-boot-starter-data-redis-2.7.18.jar;D:\repository\org\springframework\boot\spring-boot-starter\2.7.18\spring-boot-starter-2.7.18.jar;D:\repository\org\springframework\boot\spring-boot-starter-logging\2.7.18\spring-boot-starter-logging-2.7.18.jar;D:\repository\ch\qos\logback\logback-classic\1.2.12\logback-classic-1.2.12.jar;D:\repository\ch\qos\logback\logback-core\1.2.12\logback-core-1.2.12.jar;D:\repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\repository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\repository\org\springframework\data\spring-data-redis\2.7.18\spring-data-redis-2.7.18.jar;D:\repository\org\springframework\data\spring-data-keyvalue\2.7.18\spring-data-keyvalue-2.7.18.jar;D:\repository\org\springframework\data\spring-data-commons\2.7.18\spring-data-commons-2.7.18.jar;D:\repository\org\springframework\spring-tx\5.3.31\spring-tx-5.3.31.jar;D:\repository\org\springframework\spring-oxm\5.3.31\spring-oxm-5.3.31.jar;D:\repository\io\lettuce\lettuce-core\6.1.10.RELEASE\lettuce-core-6.1.10.RELEASE.jar;D:\repository\io\netty\netty-common\4.1.101.Final\netty-common-4.1.101.Final.jar;D:\repository\io\netty\netty-handler\4.1.101.Final\netty-handler-4.1.101.Final.jar;D:\repository\io\netty\netty-resolver\4.1.101.Final\netty-resolver-4.1.101.Final.jar;D:\repository\io\netty\netty-buffer\4.1.101.Final\netty-buffer-4.1.101.Final.jar;D:\repository\io\netty\netty-transport-native-unix-common\4.1.101.Final\netty-transport-native-unix-common-4.1.101.Final.jar;D:\repository\io\netty\netty-codec\4.1.101.Final\netty-codec-4.1.101.Final.jar;D:\repository\io\netty\netty-transport\4.1.101.Final\netty-transport-4.1.101.Final.jar;D:\repository\io\projectreactor\reactor-core\3.4.34\reactor-core-3.4.34.jar;D:\repository\org\reactivestreams\reactive-streams\1.0.4\reactive-streams-1.0.4.jar;D:\repository\org\springframework\boot\spring-boot-starter-cache\2.7.18\spring-boot-starter-cache-2.7.18.jar;D:\repository\org\springframework\spring-context-support\5.3.31\spring-context-support-5.3.31.jar;D:\repository\org\springframework\spring-beans\5.3.31\spring-beans-5.3.31.jar;D:\repository\org\springframework\spring-context\5.3.31\spring-context-5.3.31.jar;D:\repository\org\springframework\boot\spring-boot-starter-web\2.7.18\spring-boot-starter-web-2.7.18.jar;D:\repository\org\springframework\boot\spring-boot-starter-json\2.7.18\spring-boot-starter-json-2.7.18.jar;D:\repository\com\fasterxml\jackson\core\jackson-databind\2.13.5\jackson-databind-2.13.5.jar;D:\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.5\jackson-annotations-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.5\jackson-datatype-jdk8-2.13.5.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.5\jackson-datatype-jsr310-2.13.5.jar;D:\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.5\jackson-module-parameter-names-2.13.5.jar;D:\repository\org\springframework\boot\spring-boot-starter-tomcat\2.7.18\spring-boot-starter-tomcat-2.7.18.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.83\tomcat-embed-core-9.0.83.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.83\tomcat-embed-el-9.0.83.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.83\tomcat-embed-websocket-9.0.83.jar;D:\repository\org\springframework\spring-web\5.3.31\spring-web-5.3.31.jar;D:\repository\org\springframework\spring-webmvc\5.3.31\spring-webmvc-5.3.31.jar;D:\repository\org\springframework\spring-expression\5.3.31\spring-expression-5.3.31.jar;D:\repository\org\springframework\boot\spring-boot-starter-websocket\2.7.18\spring-boot-starter-websocket-2.7.18.jar;D:\repository\org\springframework\spring-messaging\5.3.31\spring-messaging-5.3.31.jar;D:\repository\org\springframework\spring-websocket\5.3.31\spring-websocket-5.3.31.jar;D:\repository\org\springframework\boot\spring-boot-configuration-processor\2.7.18\spring-boot-configuration-processor-2.7.18.jar;D:\repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\2.2.0\mybatis-spring-boot-starter-2.2.0.jar;D:\repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\2.2.0\mybatis-spring-boot-autoconfigure-2.2.0.jar;D:\repository\org\mybatis\mybatis\3.5.7\mybatis-3.5.7.jar;D:\repository\org\mybatis\mybatis-spring\2.0.6\mybatis-spring-2.0.6.jar;D:\repository\org\springframework\boot\spring-boot-starter-security\2.7.18\spring-boot-starter-security-2.7.18.jar;D:\repository\org\springframework\spring-aop\5.3.31\spring-aop-5.3.31.jar;D:\repository\org\springframework\security\spring-security-config\5.7.11\spring-security-config-5.7.11.jar;D:\repository\org\springframework\security\spring-security-web\5.7.11\spring-security-web-5.7.11.jar;D:\repository\org\springframework\boot\spring-boot-starter-jdbc\2.7.18\spring-boot-starter-jdbc-2.7.18.jar;D:\repository\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;D:\repository\org\springframework\spring-jdbc\5.3.31\spring-jdbc-5.3.31.jar;D:\repository\com\alibaba\druid-spring-boot-starter\1.2.23\druid-spring-boot-starter-1.2.23.jar;D:\repository\com\alibaba\druid\1.2.23\druid-1.2.23.jar;D:\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\repository\org\springframework\boot\spring-boot-autoconfigure\2.7.18\spring-boot-autoconfigure-2.7.18.jar;D:\repository\org\glassfish\jaxb\jaxb-runtime\2.3.9\jaxb-runtime-2.3.9.jar;D:\repository\org\glassfish\jaxb\txw2\2.3.9\txw2-2.3.9.jar;D:\repository\com\sun\istack\istack-commons-runtime\3.0.12\istack-commons-runtime-3.0.12.jar;D:\repository\com\sun\activation\jakarta.activation\1.2.2\jakarta.activation-1.2.2.jar;D:\repository\com\mysql\mysql-connector-j\8.2.0\mysql-connector-j-8.2.0.jar;D:\repository\org\postgresql\postgresql\42.5.1\postgresql-42.5.1.jar;D:\repository\org\checkerframework\checker-qual\3.5.0\checker-qual-3.5.0.jar;D:\ChromeCoreDownloads\wvp-GB28181-pro-master (1)\wvp-GB28181-pro-master\libs\jdbc-x86\kingbase8-8.6.0.jar;D:\repository\com\github\pagehelper\pagehelper-spring-boot-starter\1.4.6\pagehelper-spring-boot-starter-1.4.6.jar;D:\repository\com\github\pagehelper\pagehelper-spring-boot-autoconfigure\1.4.6\pagehelper-spring-boot-autoconfigure-1.4.6.jar;D:\repository\com\github\pagehelper\pagehelper\5.3.2\pagehelper-5.3.2.jar;D:\repository\com\github\jsqlparser\jsqlparser\4.5\jsqlparser-4.5.jar;D:\repository\org\springdoc\springdoc-openapi-ui\1.6.10\springdoc-openapi-ui-1.6.10.jar;D:\repository\org\springdoc\springdoc-openapi-webmvc-core\1.6.10\springdoc-openapi-webmvc-core-1.6.10.jar;D:\repository\org\webjars\swagger-ui\4.13.2\swagger-ui-4.13.2.jar;D:\repository\org\webjars\webjars-locator-core\0.50\webjars-locator-core-0.50.jar;D:\repository\com\fasterxml\jackson\core\jackson-core\2.13.5\jackson-core-2.13.5.jar;D:\repository\io\github\classgraph\classgraph\4.8.149\classgraph-4.8.149.jar;D:\repository\org\springdoc\springdoc-openapi-security\1.6.10\springdoc-openapi-security-1.6.10.jar;D:\repository\org\springdoc\springdoc-openapi-common\1.6.10\springdoc-openapi-common-1.6.10.jar;D:\repository\io\swagger\core\v3\swagger-core\2.2.2\swagger-core-2.2.2.jar;D:\repository\org\apache\commons\commons-lang3\3.12.0\commons-lang3-3.12.0.jar;D:\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-yaml\2.13.5\jackson-dataformat-yaml-2.13.5.jar;D:\repository\io\swagger\core\v3\swagger-annotations\2.2.2\swagger-annotations-2.2.2.jar;D:\repository\io\swagger\core\v3\swagger-models\2.2.2\swagger-models-2.2.2.jar;D:\repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;D:\repository\org\springframework\security\spring-security-core\5.7.11\spring-security-core-5.7.11.jar;D:\repository\org\springframework\security\spring-security-crypto\5.7.11\spring-security-crypto-5.7.11.jar;D:\repository\com\github\xiaoymin\knife4j-springdoc-ui\3.0.3\knife4j-springdoc-ui-3.0.3.jar;D:\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;D:\repository\org\springframework\boot\spring-boot-starter-aop\2.7.18\spring-boot-starter-aop-2.7.18.jar;D:\repository\org\aspectj\aspectjweaver\1.9.7\aspectjweaver-1.9.7.jar;D:\repository\javax\sip\jain-sip-ri\1.3.0-91\jain-sip-ri-1.3.0-91.jar;D:\repository\org\slf4j\log4j-over-slf4j\1.7.36\log4j-over-slf4j-1.7.36.jar;D:\repository\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar;D:\repository\com\alibaba\fastjson2\fastjson2\2.0.57\fastjson2-2.0.57.jar;D:\repository\com\alibaba\fastjson2\fastjson2-extension\2.0.57\fastjson2-extension-2.0.57.jar;D:\repository\com\alibaba\fastjson2\fastjson2-extension-spring5\2.0.57\fastjson2-extension-spring5-2.0.57.jar;D:\repository\com\squareup\okhttp3\okhttp\4.10.0\okhttp-4.10.0.jar;D:\repository\com\squareup\okio\okio-jvm\3.0.0\okio-jvm-3.0.0.jar;D:\repository\org\jetbrains\kotlin\kotlin-stdlib-common\1.6.21\kotlin-stdlib-common-1.6.21.jar;D:\repository\org\jetbrains\kotlin\kotlin-stdlib\1.6.21\kotlin-stdlib-1.6.21.jar;D:\repository\org\jetbrains\annotations\13.0\annotations-13.0.jar;D:\repository\com\squareup\okhttp3\logging-interceptor\4.10.0\logging-interceptor-4.10.0.jar;D:\repository\org\jetbrains\kotlin\kotlin-stdlib-jdk8\1.6.21\kotlin-stdlib-jdk8-1.6.21.jar;D:\repository\org\jetbrains\kotlin\kotlin-stdlib-jdk7\1.6.21\kotlin-stdlib-jdk7-1.6.21.jar;D:\repository\io\github\rburgst\okhttp-digest\2.7\okhttp-digest-2.7.jar;D:\repository\org\bitbucket\b_c\jose4j\0.9.3\jose4j-0.9.3.jar;D:\repository\org\mitre\dsmiley\httpproxy\smiley-http-proxy-servlet\1.12.1\smiley-http-proxy-servlet-1.12.1.jar;D:\repository\org\apache\httpcomponents\httpclient\4.5.14\httpclient-4.5.14.jar;D:\repository\org\apache\httpcomponents\httpcore\4.4.16\httpcore-4.4.16.jar;D:\repository\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;D:\repository\com\alibaba\easyexcel\3.3.2\easyexcel-3.3.2.jar;D:\repository\com\alibaba\easyexcel-core\3.3.2\easyexcel-core-3.3.2.jar;D:\repository\com\alibaba\easyexcel-support\3.3.2\easyexcel-support-3.3.2.jar;D:\repository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar;D:\repository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar;D:\repository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;D:\repository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar;D:\repository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar;D:\repository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar;D:\repository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar;D:\repository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar;D:\repository\org\apache\commons\commons-csv\1.8\commons-csv-1.8.jar;D:\repository\org\ehcache\ehcache\3.10.8\ehcache-3.10.8.jar;D:\repository\javax\cache\cache-api\1.1.1\cache-api-1.1.1.jar;D:\repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;D:\repository\org\apache\commons\commons-compress\1.24.0\commons-compress-1.24.0.jar;D:\repository\com\github\oshi\oshi-core\6.2.2\oshi-core-6.2.2.jar;D:\repository\net\java\dev\jna\jna\5.12.1\jna-5.12.1.jar;D:\repository\net\java\dev\jna\jna-platform\5.12.1\jna-platform-5.12.1.jar;D:\repository\org\springframework\session\spring-session-core\2.7.4\spring-session-core-2.7.4.jar;D:\repository\org\springframework\spring-jcl\5.3.31\spring-jcl-5.3.31.jar;D:\repository\com\google\guava\guava\32.1.3-jre\guava-32.1.3-jre.jar;D:\repository\com\google\guava\failureaccess\1.0.1\failureaccess-1.0.1.jar;D:\repository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;D:\repository\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar;D:\repository\com\google\errorprone\error_prone_annotations\2.21.1\error_prone_annotations-2.21.1.jar;D:\repository\com\google\j2objc\j2objc-annotations\2.8\j2objc-annotations-2.8.jar;D:\repository\org\apache\ftpserver\ftpserver-core\1.2.0\ftpserver-core-1.2.0.jar;D:\repository\org\apache\mina\mina-core\2.1.6\mina-core-2.1.6.jar;D:\repository\org\apache\ftpserver\ftplet-api\1.2.0\ftplet-api-1.2.0.jar;D:\repository\org\projectlombok\lombok\1.18.30\lombok-1.18.30.jar;D:\repository\io\github\sevdokimov\logviewer\log-viewer-spring-boot\1.0.10\log-viewer-spring-boot-1.0.10.jar;D:\repository\org\springframework\boot\spring-boot\2.7.18\spring-boot-2.7.18.jar;D:\repository\io\github\sevdokimov\logviewer\log-viewer\1.0.10\log-viewer-1.0.10.jar;D:\repository\io\github\sevdokimov\logviewer\log-viewer-frontend\1.0.10\log-viewer-frontend-1.0.10.jar;D:\repository\com\google\code\gson\gson\2.9.1\gson-2.9.1.jar;D:\repository\com\github\ben-manes\caffeine\caffeine\2.9.3\caffeine-2.9.3.jar;D:\repository\com\typesafe\config\1.3.3\config-1.3.3.jar;D:\repository\org\mozilla\rhino\1.7.13\rhino-1.7.13.jar;D:\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;D:\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;D:\repository\org\springframework\spring-core\5.3.31\spring-core-5.3.31.jar" com.genersoft.iot.vmp.VManageBootstrap ___ __ ___ ___ ________ ________ ________ ________ |\ \ |\ \|\ \ / /|\ __ \ |\ __ \|\ __ \|\ __ \ \ \ \ \ \ \ \ \ / / | \ \|\ \ ____________\ \ \|\ \ \ \|\ \ \ \|\ \ \ \ \ __\ \ \ \ \/ / / \ \ ____\\____________\ \ ____\ \ _ _\ \ \\\ \ \ \ \|\__\_\ \ \ / / \ \ \___\|____________|\ \ \___|\ \ \\ \\ \ \\\ \ \ \____________\ \__/ / \ \__\ \ \__\ \ \__\\ _\\ \_______\ \|____________|\|__|/ \|__| \|__| \|__|\|__|\|_______| 2025-08-21 16:01:04.159 [main] INFO --- com.genersoft.iot.vmp.VManageBootstrap: 55 Starting VManageBootstrap using Java 1.8.0_131 on DESKTOP-UF2P6NE with PID 174620 (D:\ChromeCoreDownloads\wvp-GB28181-pro-master (1)\wvp-GB28181-pro-master\target\classes started by lenovo in D:\ChromeCoreDownloads\wvp-GB28181-pro-master (1)\wvp-GB28181-pro-master) 2025-08-21 16:01:04.163 [main] INFO --- com.genersoft.iot.vmp.VManageBootstrap: 638 The following 1 profile is active: "274-dev" 2025-08-21 16:01:05.021 [main] INFO --- o.s.context.annotation.ConfigurationClassParser: 471 Properties location [classpath:git.properties] not resolvable: class path resource [git.properties] cannot be opened because it does not exist 2025-08-21 16:01:05.687 [main] INFO --- o.s.d.r.config.RepositoryConfigurationDelegate: 262 Multiple Spring Data modules found, entering strict repository configuration mode 2025-08-21 16:01:05.689 [main] INFO --- o.s.d.r.config.RepositoryConfigurationDelegate: 132 Bootstrapping Spring Data Redis repositories in DEFAULT mode. 2025-08-21 16:01:05.807 [main] INFO --- o.s.d.r.config.RepositoryConfigurationDelegate: 201 Finished Spring Data repository scanning in 107 ms. Found 0 Redis repository interfaces. 2025-08-21 16:01:06.525 [main] INFO --- o.s.boot.web.embedded.tomcat.TomcatWebServer: 108 Tomcat initialized with port(s): 8080 (http) 2025-08-21 16:01:06.535 [main] INFO --- org.apache.coyote.http11.Http11NioProtocol: 173 Initializing ProtocolHandler ["http-nio-8080"] 2025-08-21 16:01:06.537 [main] INFO --- org.apache.catalina.core.StandardService: 173 Starting service [Tomcat] 2025-08-21 16:01:06.537 [main] INFO --- org.apache.catalina.core.StandardEngine: 173 Starting Servlet engine: [Apache Tomcat/9.0.83] 2025-08-21 16:01:06.797 [main] INFO --- o.a.c.core.ContainerBase.[Tomcat].[localhost].[/]: 173 Initializing Spring embedded WebApplicationContext 2025-08-21 16:01:06.797 [main] INFO --- o.s.b.w.s.c.ServletWebServerApplicationContext: 292 Root WebApplicationContext: initialization completed in 2595 ms 2025-08-21 16:01:07.117 [main] INFO --- c.a.d.s.b.a.DruidDataSourceAutoConfigure: 68 Init DruidDataSource 2025-08-21 16:01:07.235 [main] ERROR --- o.s.boot.web.embedded.tomcat.TomcatStarter: 61 Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'proxyServletConfig': Unsatisfied dependency expressed through field 'mediaServerService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mediaServerServiceImpl': Unsatisfied dependency expressed through field 'mediaServerMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mediaServerMapper' defined in file [D:\ChromeCoreDownloads\wvp-GB28181-pro-master (1)\wvp-GB28181-pro-master\target\classes\com\genersoft\iot\vmp\storager\dao\MediaServerMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/genersoft/iot/vmp/conf/MybatisConfig.class]: Unsatisfied dependency expressed through method 'sqlSessionFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class]: Invocation of init method failed; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class 2025-08-21 16:01:07.255 [main] INFO --- org.apache.catalina.core.StandardService: 173 Stopping service [Tomcat] 2025-08-21 16:01:07.268 [main] WARN --- org.apache.catalina.loader.WebappClassLoaderBase: 173 The web application [ROOT] appears to have started a thread named [lettuce-timer-3-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: java.lang.Thread.sleep(Native Method) io.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:600) io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:496) io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:748) 2025-08-21 16:01:07.269 [main] WARN --- o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext: 599 Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat 2025-08-21 16:01:07.287 [main] INFO --- o.s.b.a.l.ConditionEvaluationReportLoggingListener: 136 Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2025-08-21 16:01:07.301 [main] ERROR --- o.s.b.diagnostics.LoggingFailureAnalysisReporter: 40 *************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class Action: Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the classpath. If you have database settings to be loaded from a particular profile you may need to activate it (the profiles 274-dev are currently active). Process finished with exit code 1 分析错误
最新发布
08-22
<think>我们正在处理一个Spring Boot应用启动失败的问题,错误信息是:"Failed to determine a suitable driver class"。这通常发生在Spring Boot无法自动配置数据源(DataSource)时。根据引用[1]和引用[2],我们可以分析以下可能的原因和解决方案。 ### 问题分析 1. **缺少数据库驱动依赖**:Spring Boot需要相应的数据库驱动来连接数据库。例如,使用MySQL需要添加`mysql-connector-java`依赖。 2. **数据源配置错误**:在`application.properties`或`application.yml`中,数据源配置(如`spring.datasource.url`)可能缺失或格式不正确。 3. **Spring Boot版本与依赖不兼容**:特别是对于Spring Boot 3.x,一些依赖需要特定版本或使用`spring-boot3-starter`(如引用[2]提到的动态数据源依赖需要`dynamic-datasource-spring-boot3-starter`)。 4. **依赖冲突**:可能存在多个数据源依赖冲突,导致自动配置失败。 ### 解决方案 #### 1. 检查数据库驱动依赖 确保在`pom.xml`(Maven)或`build.gradle`(Gradle)中添加了正确的数据库驱动。例如,对于MySQL: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> <!--使用适合你数据库版本的驱动 --> </dependency> ``` #### 2. 检查数据源配置 在`application.properties`中,确保配置了数据源URL、用户名和密码: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` #### 3. 检查Spring Boot版本与依赖兼容性 - 如果你使用的是Spring Boot 2.7.x,确保依赖的版本兼容。例如,动态数据源依赖应为`dynamic-datasource-spring-boot-starter`(不带`3`)。 - 对于Spring Boot 3.x,必须使用支持Spring Boot 3的依赖,如引用[2]所示:`dynamic-datasource-spring-boot3-starter`。 #### 4. 排除自动配置(可选) 如果项目不需要数据库,可以在启动类上排除数据源自动配置: ```java @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 5. 检查依赖冲突 使用`mvn dependency:tree`或`gradle dependencies`命令检查依赖树,排除重复或冲突的依赖。 ### 总结 根据错误信息"Failed to determine a suitable driver class",重点检查数据库驱动依赖和数据源配置。同时,注意Spring Boot版本与依赖的兼容性。按照上述步骤排查,通常可以解决问题。 §§相关问题§§ 1. 如何解决Spring Boot中`DataSource`配置失败的问题? 2. Spring Boot 2.x和3.x在数据源配置上有哪些主要区别? 3. 如何在Spring Boot中配置多数据源?</think>### Spring Boot数据源配置错误分析 您遇到的错误信息`Failed to determine a suitable driver class`通常发生在Spring Boot无法自动配置数据源时。以下是详细分析和解决方案: #### 核心问题原因 1. **驱动类未识别**:Spring Boot无法自动检测到合适的JDBC驱动类 2. **配置缺失**:数据源URL未在配置文件中指定(如`application.properties`) 3. **依赖问题**:缺少数据库驱动依赖或版本不兼容 4. **Spring Boot版本兼容性**:如引用[2]指出,Spring Boot 3.x需要特定格式的依赖命名 #### 解决方案步骤 1. **检查依赖配置**(关键步骤) 在`pom.xml`中添加数据库驱动依赖(以MySQL为例): ```xml <!-- Spring Boot 2.7.x 适用 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> ``` 2. **配置数据源属性** 在`application.properties`中添加: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/yourdb spring.datasource.username=root spring.datasource.password=yourpassword # 明确指定驱动类(可选但推荐) spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 3. **检查自动配置** 确保未禁用数据源自动配置: ```java @SpringBootApplication public class YourApplication { ... } // 不要排除DataSourceAutoConfiguration ``` 4. **Spring Boot 3.x特殊处理**(如适用) 如引用[2]所述,Spring Boot 3需要特定依赖命名: ```xml <!-- Spring Boot 3.x 必须使用boot3-starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <version>${dynamic-ds.version}</version> </dependency> ``` #### 常见错误排查 - 🔍 检查依赖树:`mvn dependency:tree` 确认驱动是否存在 - 🔍 验证配置文件位置:确保`application.properties`在`src/main/resources`下 - 🔍 检查数据库服务状态:确认数据库实例正在运行 - 🔍 版本兼容性:Spring Boot 2.7.x建议使用MySQL驱动8.0.x版本 #### 解决方案验证 成功配置后,启动日志应显示类似信息: ``` Initializing DataSource with URL: jdbc:mysql://localhost:3306/yourdb ``` ### 相关问题 1. 如何解决Spring Boot 3中`dynamic-datasource`找不到数据源的问题?[^2] 2. Spring Boot 2.x和3.x在数据源自动配置上有哪些主要区别? 3. 如何手动配置多数据源而不使用自动配置? 4. 当使用非关系型数据库(如MongoDB)时如何避免数据源配置错误? [^1]: 数据库配置未生效的典型错误信息 [^2]: Spring Boot 3中数据源依赖的特殊要求
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值