1、新建一个空工程learn_spingclound,
2、新建一个maven模块tuyspringclund,
3、配置 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.tuy</groupId>
<artifactId>tuy-springclound</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>user-service</module>
<module>consumer-demo</module>
<module>eureka-server</module>
<module>gatewaydemo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
<mapper.starter.version>2.1.5</mapper.starter.version>
<mysql.version>5.1.46</mysql.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<!--通过import可以继承spring-cloud-dependencies -->
<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>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4、在模块tuyspringclund下,新建一个服务提供模块 userservice,
5、配置模块 userservice的 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">
<parent>
<artifactId>tuy-springclound</artifactId>
<groupId>com.tuy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 通用Mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--EurekaServer客户端依赖,会自动将服务注册到EurekaServer服务地址列表 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<!--不传递依赖-->
<optional>true</optional>
</dependency>
<!-- 整合事务配置需要的依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
6、在模块 userservice下 新建包com.tuy.user,
7、在模块 userservice下 新建类com.tuy.user.controller.UserController 类
package com.tuy.user.controller;
import com.tuy.user.pojo.User;
import com.tuy.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user") //映射路径
public class UserController {
@Autowired
private UserService userService;
//业务方法
@GetMapping("/{id}")
public User queryById(@PathVariable Long id){
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
return userService.queryById(id);
}
}
8、新建com.tuy.user.pojo.User类
package com.tuy.user.pojo;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
//实体类
@Data
@Table(name = "tb_user")
public class User{
// id
@Id
//开启主键自动回填
@KeySql(useGeneratedKeys = true)
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 创建时间
private Date created;
// 更新时间
private Date updated;
// 备注
private String note;
}
9、新建 com.tuy.user.mapper.UserMapper类
package com.tuy.user.mapper;
import com.tuy.user.pojo.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper<User> {
}
9、新建com.tuy.user.service.userService类
package com.tuy.user.service;
import com.tuy.user.mapper.UserMapper;
import com.tuy.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired //注入
private UserMapper userMapper;
/**
* 根据主键查询用户
* @param id 用户id
* @return 用户
*/
public User queryById(Long id){
return userMapper.selectByPrimaryKey(id);
}
}
10、新建启动类
package com.tuy.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;
//启动引导类
@SpringBootApplication
@MapperScan("com.tuy.user.mapper") //通用mapper扫描
@EnableDiscoveryClient //开启Eureka客户端发现功能
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
//启动多个UserApplication
//在 edit Configuration中的Emvironment的Vm option里面写入
//-Dport=9091
//在 edit Configuration中复制一个UserApplication,
//在 edit Configuration中的Emvironment的Vm option里面写入
//-Dport=9092
11、新建配置文件 application.yml
server:
port: ${port:9091}
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud
username: root
password: root
#配置本应用的名称
application:
name: user-service
mybatis:
type-aliases-package: com.tuy.user.pojo
eureka:
client:
service-url:
#eureka的地址
defaultZone: http://127.0.0.1:10086/eureka
instance:
# 更倾向使用ip地址,而不是host名
prefer-ip-address: true
# ip地址
ip-address: 127.0.0.1
# 续约(向Eureka服务器发送心跳)间隔,默认30秒
lease-renewal-interval-in-seconds: 5
# 服务失效时间,默认90秒
lease-expiration-duration-in-seconds: 5
//----------
13 在模块tuyspringclund下新建一个模块gatewaydemo,
14 、配置模块gatewaydemo的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">
<parent>
<artifactId>tuy-springclound</artifactId>
<groupId>com.tuy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gatewaydemo</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
15、在模块gatewaydemo下新建包com.tuy.gateway
16、新建局部过滤器 com.tuy.gateway .MyParamGatewayFilterFactory
package com.tuy.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
//局部过滤器
@Component
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
static final String PARAM_NAME = "param";
public MyParamGatewayFilterFactory() {
super(Config.class);
}
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME);
}
@Override
public GatewayFilter apply(Config config) {
//jdk8才这么写
return (exchange, chain) -> {
// http://localhost:10010/api/user/8?name=tuuuu config.param ==> name
//获取请求参数中param对应的参数名 的参数值
ServerHttpRequest request = exchange.getRequest();
//是否包含参数 name ,有就有输出
if(request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).
forEach(value -> System.out.printf("------------局部过滤器--------%s = %s------", config.param, value));
}
return chain.filter(exchange);
};
}
public static class Config{
//对应在配置过滤器的时候指定的参数名 ,在配置文件中配置的 - MyParam=name
private String param; //name
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
}
17、新建全局过滤器 com.tuy.gateway .MyGlobalFilter
package com.tuy.gateway.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
// http://localhost:10010/api/user/8?name=354354&token=2
//全局过滤器
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("--------------全局过滤器MyGlobalFilter------------------");
String token = exchange.getRequest().getQueryParams().getFirst("token"); //exchange.getRequest().getQueryParams().get("token");
if(StringUtils.isBlank(token)){ //如果为空
//设置响应状态码为未授权
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete(); //不再执行后面的过滤请求
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
//值越小越先执行
return 1;
}
}
18、新建启动类
package com.tuy.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//访问测试 http://127.0.0.1:10010/user/8 这个地址实际会访问到 http://127.0.0.1:9091/user/8
//gateway 网关一般给终端请求使用
@SpringBootApplication
@EnableDiscoveryClient
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
}
19、新建配置文件 applicaiton.yml
server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
# 路由id,可以任意
# - 代表多个
- id: user-service-route
# 代理的服务地址
#uri: http://127.0.0.1:9091
# lb表示从eureka中获取具体服务 ,user-service 是某个注册到eureka的服务
uri: lb://user-service
# 路由断言(条件): 可以匹配映射路径
predicates:
#路径包含有user都转到 http://127.0.0.1:9091
#- Path=/user/**
# 全部
#- Path=/**
- Path=/api/user/**
#过滤器
filters:
# 添加请求路径的前缀, http://localhost:10010/8 代表 http://localhost:9091/user/8
#- PrefixPath=/user
#1表示过滤1个路径,2表示两个路径,以此类推 , http://localhost:10010/api/user/8 代表 http://localhost:9091/user/8
# /api/user/** 去除一个/api
- StripPrefix=1
#配置过滤器 请求路径的参数名称
- MyParam=name
# 默认过滤器,对所有路由都生效
default-filters:
# AddResponseHeader给响应头添加, X-Response-Foo是键 ,Bar是值
- AddResponseHeader=X-Response-Foo, Bar
# - AddResponseHeader=abc-myname,heima
#跨域配置
globalcors:
corsConfigurations:
'[/**]':
#allowedOrigins: * # 这种写法或者下面的都可以,*表示全部
allowedOrigins:
- "http://docs.spring.io"
allowedMethods:
- GET
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
ribbon:
ConnectTimeout: 1000
ReadTimeout: 2000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 0