约定大于配置大于编码
新建工作空间
1.新建一个maven工程(当作总工程,下面就新建小的moudle),配置名字,包名,之类的。
出现这个爆红
找不到插件 ‘maven-clean-plugin:3.1.0‘
解决方法:加入代码: 内联代码片
。
<groupId>org.apache.maven.plugins</groupId>
插入位置
maven爆红
解决方法:原因没有导入相应依赖,导入依赖。
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</dependency>
2.设置字符编码为UTF-8
3.注解生效激活
4.java编译版本选择
5.文件类型过滤,就和git提交过滤一样,将指定的后缀文件不显示出来,让目录结构更好看。
eg:
配置过滤文件
配置之后过滤了的就没了。
对父工程pom文件进行操作
前置知识
Maven中pom.xml的packaging类型
项目的打包类型:pom、jar、war
项目中一般使用maven进行模块管理,每个模块下对应都有一个pom文件,pom文件中维护了各模块之间的依赖和继承关系。项目模块化可以将通用的部分抽离出来,方便重用;修改一部分代码不再是build整个项目,缩短了build时间;此外各模块都有自己的pom文件,结构更清晰。
使用maven进行模块划分管理,一般都会有一个父级项目,pom文件除了GAV(groupId, artifactId, version)是必须要配置的,另一个重要的属性就是packaging打包类型,所有的父级项目的packaging都为pom,packaging默认是jar类型,如果不作配置,maven会将该项目打成jar包。作为父级项目,还有一个重要的属性,那就是modules,通过modules标签将项目的所有子项目引用进来,在build父级项目时,会根据子模块的相互依赖关系整理一个build顺序,然后依次build。
而对于各个子项目,需要在其对应的pom文件开头申明对父级项目的引用,通过GAV实现。对于子项目自己的GAV配置,GV如果不配置,则会从父级项目的配置继承过来。子模块可通过dependencies标签来添加自己的依赖,此外子类项目的packaging值只能是war或者jar,前面已经说过,packaging默认是jar类型。如果是需要部署的项目,则需要打包成war类型,如果只是内部调用或者是作服务使用,则推荐打包成jar类型。
因为我们创建的是一个父项目所以说应该设置为pom,后面将modules导入,这样方便统一管理依赖。
<dependencyManagement>
Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。
通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。
使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。
Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个
dependencyManagement 元素中指定的版本号。
这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;另外如果某个子项目需要另外的一个版本,只需要声明version就可。
* dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
* 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,
才会从父项目中继承该项,并且version和scope都读取自父pom;
* 如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
跳过单元测试
构建第一个子模块
也是建立一个maven工程
一个maven项目就只有这些东西
resources new yml文件,springboot的配置文件
泛型分别使用在类和方法上的情况说明
参考连接:
https://blog.csdn.net/weixin_45311284/article/details/103623764
主要注意的就是,使用泛型可以在参数里面写上泛型,接收不确定的参数(比如说,多个对象都会调用一个方法并传入对象自己,那么该方法就该有普遍性,就可以使用Object object来接收对象,泛型的作用就和object一样可以接收不确定的参数对象,并对他操作。)
创建模块标准步骤
mapper.xml文件写法
在浏览器测试时Mysql驱动包报错
原因:因为使用的时8点几的版本,驱动jar包的名字变了,并且使用url时应该设置时区
使用JDBC连接MySQL时,出现以下错误:
Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
问题所在:在查阅相关资料之后,得知是由于jdbc驱动包名引发的问题
5.x版本的驱动文件jar包对应的是:
Class.forName("com.mysql.jdbc.Driver");
语句来加载数据库驱动
而我使用的是8.0x版本的数据库驱动文件,对此,需要将加载数据库驱动的语句更改为:
Class.forName("com.mysql.cj.jdbc.Driver");
除此之外:
url的设置也得进行修改,原本的url如下:
String ur="jdbc:mysql://127.0.0.1:3306/student";
应修改为如下:String url="jdbc:mysql://127.0.0.1:3306/student?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";
其中student是数据库名
8.0x是不需要建立ssl连接的,你需要显示关闭,即url中的&useSSL=false;
serverTimezone=GMT%2B8"是进行时区的设置`
再给一个url样例如下:
Url="jdbc:mysql://localhost:3306/db3?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&
autoReconnect=true";
url基本格式如下:
连接地址+ssl连接关闭+字符集为utf-8+时区设置
在测试post请求时浏览器报错,因为大多数浏览器不支持post请求,所以说要使用postman工具进行测试
在测试post接口时报400错误,把@Requestbody注解先注解掉就成功了。
原因:待补充。。。。
实现热部署(就是每次修改完代码之后不需要重新启动程序就能更新)
1.引入devtools依赖,修改配置文件开启热部署
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
2.修改配置文件开启热部署
spring:
devtools:
restart:
enabled: true #设置开启热部署
additional-paths: src/main/java #重启目录
exclude: WEB-INF/**
freemarker:
cache: false #页面不加载缓存,修改即时生效
3.工程添加pluging
<build>
<finalName>你自己的工程名字</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
4.开启idea自动构建项目
开启允许自动构建
配置完重启idea
泛型:
分为泛型方法和泛型类
泛型方法写在返回值之前
泛型类写在类名之后
作用:接收不同类型的对象或者参数,而且泛型可以在声明是继承或者implements某个类实现其功能。
泛型方法就是将泛型作为参数,在调用该方法时可以传入不同的参数,但是在调用时不能限制传入参数是什么类型。
eg:泛型类可以接收不同的类型参数,在new对象时可以限制传入参数类型。
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<String> stringBox = new Box<String>();
integerBox.add(new Integer(10));
stringBox.add(new String("菜鸟教程"));
System.out.printf("整型值为 :%d\n\n", integerBox.get());
System.out.printf("字符串为 :%s\n", stringBox.get());
}
}
restTemplate进行不同模块之间的调用
使用:
使用restTemplate访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
order模块,因为浏览器无法直接使用post请求所以说包装一层使用get请求,然后由这个模块去调用另外一个模块的服务(使用restTemplate方法),这样浏览器就能直接在地址栏间接调用post的接口了
因为不同模块都有相同的entity实体类,所以说我们想把他打成jar包,父工程调用就都可以使用了,这个模块是不对外展示的。
服务注册中心
什么是服务治理
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
就是各个模块之间纵横交错的调用(比如说之前的order模块使用restTempate去调用支付模块一样),然后就需要一种管理机制来提供服务治理的落地实现服务调用、负载均衡、容错等功能。
什么是服务注册与发现
Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
Eureka包含两个组件:Eureka Server和Eureka Client
Eureka Server提供服务注册服务
各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
EurekaClient通过注册中心进行访问
是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
Eurake的安装
首先也是新建一个模块,改pom写yml设置主启动然后写业务类(由于Eurake主要是起到服务注册治理的作用,所以说不用写业务类,到时候把其他服务注入到Eurake就行)。
得在主启动类上加上@EnableEurekaServer注解让该项目作为SpringCloud中的注册中心。
服务(server)入驻Eurake
1.加入Eurake client端的依赖
2.改配置yml,主启动类加上@EnableEurekaClient注解
3.测试(先启动Eurake然后启动服务)
Eureka工作流程
就差不多是服务注册然后用户去Eureka获取地址然后自己访问。
问题:微服务RPC远程服务调用最核心的是什么
高可用,试想你的注册中心只有一个only one, 它出故障了那就呵呵( ̄▽ ̄)"了,会导致整个为服务环境不可用,所以
解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错
Eureka集群搭建
互相注册,相互守望
模拟集群的方法:在本地host文件里面添加域名映射,使用不同端口号,模拟不同机器。
模拟集群和相互注册
1.域名映射
2.实现相互注册
因为在写Eureka集群配置文件时,直接指定的端口号说明用的就是本机的,就是localhost,那个hostname只是在服务器端的名称不是他的域名。
订单服务访问地址不能写死,实现负载均衡(默认的轮询)
//public static final String PAYMENT_SRV = "http://localhost:8001";
// 通过在eureka上注册过的微服务名称调用
public static final String PAYMENT_SRV = "http://CLOUD-PAYMENT-SERVICE";(因为在配置文件里面实现了入驻,所以说可以直接使用注册名称来访问,只是要开启负载均衡的能力。)
并且赋予resttemplate负载均衡的功能,使用 @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力(写在配置类里面)
@ComponentScan(主启动类上面的@SpringApplication里面有这个注解)会扫描本包和包子包的注解信息
Eureka在配置文件会写上自己的服务器名字就是域名其实,并且生产者消费者都注册到Eureka里面,导致消费者可以直接通过service名称加路径的方式去完成URL。
禁止Eureka自我保护机制,机制的关闭在Eureka上面进行,心跳发送间隔和多久没jian
zookeeper和consul都是在写配置文件时要写上主机地址(服务注册到哪个地方)
浏览器默认访问端口是8,访问路径应该是协议,域名端口号,然后访问路径。
http://localhost:8080/lujin
eg:https://i.cnblogs.com/posts/edit
服务熔断就是防止雪崩出现使用的兜底策略,比如说完成一个请求内部a调用b,b会去调用c,c调用d,d调e,然而要是这里其中一个服务不可用就会导致走不下去,请求等待,大量请求就会把cpu撑满,导致雪崩,服务熔断就是为这种情况发生时而采用的一种策略(兜底策略),就是发生了这种情况该怎么去处理,hystrix就是一个代表。
要是yml文件没识别出来去模块结构看看对应模块右键add添加Spring的支持。