官网自述: Spring Cloud 为开发者提供了快速构建分布式系统中一些常用模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)。分布式系统的协调导致了样板模式,使用 Spring Cloud 开发人员可以快速建立实现这些模式的服务和应用程序。它们将适用于任何分布式环境,包括开发人员自己的笔记本电脑、裸机数据中心和托管平台(如 Cloud Foundry)。
快速开始
快速开始springCloud可以从start.spring.io
也可以从springboot中添加:
特别注意:springCloud和springBoot有相应对应版本,不然会出现奇怪问题
对应版本:(2021.12.24 取自官网(Spring Cloud)供以参考)
Spring Cloud Dalston、Edgware、Finchley 和 Greenwich 都已达到生命周期终止状态,不再受支持。
对应依赖坐标:
<properties><!-- 同一依赖管理 -->
<!-- 注意参考springBoot对应依赖 -->
<spring.cloud-version>Hoxton.SR8</spring.cloud-version>
<!-- 注意适配自己的mysql -->
<mapper.starter.version>2.1.5</mapper.starter.version>
<mysql.version>8.0.23</mysql.version>
</properties>
<dependencyManagement><!-- 依赖管理,没有实际导入 -->
<dependencies>
<!-- 该依赖(spring-cloud-dependencies)管理所有springCloud版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper.starter.version}</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 编译期插件,用于简化代码,生成getter,setter等 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
注意:发布系列包含 spring-cloud-dependencies
和 spring-cloud-starter-parent
.有两种管理依赖方式,可以像使用父对象一样使用spring-boot-starter-parent
(如果使用的是 Maven)。
spring-cloud-dependencies
和 spring-cloud-starter-parent如同springBoot类似,是基于BOM和POM进行的两种依赖管理方式
使用springBoot添加管理好了springCloud依赖后,环境搭建完成。可以配置为父工程,也可以单独配置,可以引入具体服务了。
使用具体SpringCloud工具:
以eureka为服务中心
Eurekahttps://github.com/Netflix/eureka
云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
在springBoot配置文件application.yml中添加对应配置参数
server: #server相关 port: 8888 #配置端口参数,用于Eureka后台访问 spring: application: name: eureka-server #服务名称,注册后Eureka后台会显示该服务名称 #spring.application.name 和 eureka.instance.appname 来设置appname。 #spring.application.name的优先级比eureka.instance.appname高 #如果两个都设置,则显示spring.application.name。#将eureka-server自我注册,也可以不注册,注册后可以和其他eureka-server集群 eureka: client: register-with-eureka: true #配置是否自我注册,默认就是true serviceUrl: #注册中心url defaultZone: http://127.0.0.1:8888/eureka instance: prefer-ip-address: true #开启指定注册ip地址 ip-address: 127.0.0.1
在springBoot启动入口类中添加注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer //添加EurekaServer注解
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
//SpringBootApplication请在注解中添加exclude={DataSourceAutoConfiguration.class}
//作用是自动配置DataSource
public class DemoApplication {
public static void main(String[] args) {
System.out.println("springboot启动入口");
SpringApplication.run(DemoApplication.class, args);
System.out.println("springboot启动结束");
}
}
然后run:
启动中间可能会报错:原因是注册自身,服务还没启动,启动后就不会报错了,不用理会
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
直到看到,springboot启动结束,启动结束,访问:http://localhost:8888/
EurekaServer配置成功!下面进行EurekaService配置,服务将会创建一个简单的基于mysql的查询服务,
大概就是创建一个新的SpringBoot项目(要加入上面的依赖环境spring-cloud-dependencies),向pom中添加如下依赖:
<dependencies>
<!-- eureka-client
客户端包含服务注册和服务调用
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring web MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 通用mapper
单表快速开发神器,可以类比逆向工程,启动器中有一系列向包
包括,mybatis等,可以在maven中了解一下
-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
在springBoot启动入口中做如下改变:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient//客户端注册,兼容多个注册中心
@SpringBootApplication
@MapperScan("top.mypapa.demo.mapper") //使用通用Mapper的扫描
public class DemoApplication {
public static void main(String[] args) {
System.out.println("springboot启动入口");
SpringApplication.run(DemoApplication.class, args);
System.out.println("springboot启动结束");
}
//向springBoot中添加restTemplate,springCloud用于http交互的api,一会儿测试用
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在application.yml中添加如下配置:
server: #server相关 port: 8001 #暴露服务的端口 eureka: #配置解释同上 client: serviceUrl: defaultZone: http://192.168.8.129:8888/eureka logging: #日志信息 level: root: warn #配置日志全局warn级别 com.example.demo: debug #将服务Api配置为debug级别,方便调试 spring: datasource: #数据库连接池配置,不配置连接池下有默认连接池 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.8.129:3306/travel username: root password: root application: #服务名称,同上 name: test-service mybatis: #mybatis配置,配置pojo包位置 type-aliases-package: top.mypapa.demo.pojo
我模拟用的数据库叫travel,使用通用Mapper查询用户表tab_user,测试数据如下:
{"uid":7,"username":"xiaochen","password":"Aa234567890","name":"小陈","birthday":"2021-03-02T00:00:00.000+0000","sex":"男","telephone":"18881840000","email":"1928298278@qq.com","code":"dc67cea2cc334ab6bdca6aefebc67bdb"}
使用通用Mapper,先创建通用mapper对应格式的user实体
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.Date;
/**
* 通用mapper用法
* 先创建表对应实体
*/
@Data//自动生成方法(lombok)
@Table(name = "tab_user")//表名,默认为类名
public class User implements Serializable {
@Id//主键
@KeySql(useGeneratedKeys = true)//自增主键
private Integer uid;
private String username;
private String password;
private String name;
private Date birthday;
private String sex;
private String telephone;
private String email;
private String code;
//备注
@Transient//不进行SQL添加
private String note;
}
两个测试Mapper,普通的:
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
/**
* 正经mybatis操作
*/
@Repository
public interface TestMapper {
@Select("SELECT uid FROM tab_user WHERE uid = 7 ")
public String getUserByID();
}
通用mapper对接user表:(实现继承通用mapper接口就可以)
package top.mypapa.demo.mapper;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
import top.mypapa.demo.pojo.User;
/**
* 通用mapper使用
*/
@Repository
public interface TestTKMapper extends Mapper<User> {}
直接给出controller,由于是测试就不写service层了:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import top.mypapa.demo.mapper.TestTKMapper;
import top.mypapa.demo.pojo.User;
@Controller
public class TestController {
@Autowired
TestTKMapper testMapper;
@GetMapping("test")
@ResponseBody
@Transactional
public User test() throws Exception {
return testMapper.selectByPrimaryKey(7);
}
}
然后run:,成功看到,springboot启动结束,在访问http://localhost:8888/
看到:
证明服务启动成功,并且成功向Eureka中注册了服务,写个测试类尝试调用:
这里我使用的是docker先将服务发布到服务器,后运行的,也可以复制一份运行,因为需要springBoot环境
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import top.mypapa.demo.mapper.TestTKMapper;
import top.mypapa.demo.pojo.User;
import org.springframework.boot.test.context.SpringBootTest;
import java.net.URI;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Autowired
TestTKMapper testMapper;
@Autowired
RestTemplate restTemplate;
@Autowired
DiscoveryClient discoveryClient;
@Test
public void contextLoads() {
//测试直接查询
User user = testMapper.selectByPrimaryKey(7);
System.out.println(user);
//直接通过url访问查看结果
User u = restTemplate.getForObject("http://192.168.8.129:8001/test", User.class);
System.out.println("返回user:\n"+u);
//通过Eureka拉取服务查询
List<ServiceInstance> instances = discoveryClient.getInstances("test-service");
ServiceInstance serviceInstance = instances.get(0);
URI uri = serviceInstance.getUri();
System.out.println("uri\n"+uri);
System.out.println(restTemplate.getForObject(uri+"/test",String.class));
}
}
结果如下:
User(uid=7, username=xiaochen, password=Aa234567890, name=小陈, birthday=Tue Mar 02 00:00:00 CST 2021, sex=男, telephone=18881840000, email=1928298278@qq.com, code=dc67cea2cc334ab6bdca6aefebc67bdb, note=null)
返回user:
User(uid=7, username=xiaochen, password=Aa234567890, name=小陈, birthday=Tue Mar 02 08:00:00 CST 2021, sex=男, telephone=18881840000, email=1928298278@qq.com, code=dc67cea2cc334ab6bdca6aefebc67bdb, note=null)
uri
http://LAPTOP-IASEGG4O:8001
{"uid":7,"username":"xiaochen","password":"Aa234567890","name":"小陈","birthday":"2021-03-01T16:00:00.000+0000","sex":"男","telephone":"18881840000","email":"1928298278@qq.com","code":"dc67cea2cc334ab6bdca6aefebc67bdb","note":null}
快速入门完美成功!