方案:
1.基于数据库形式实现
2.基于配置中心实现(不推荐,维护性比较差,对服务的性能不是很好)
sql脚本
CREATE TABLE `gateway` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`route_id` varchar(11) DEFAULT NULL,
`route_name` varchar(255) DEFAULT NULL,
`route_pattern` varchar(255) DEFAULT NULL,
`route_type` varchar(255) DEFAULT NULL,
`route_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
工具类
package com.huahailong.dynamicConfig;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import com.huahailong.dynamicConfig.domain.GateWay;
import reactor.core.publisher.Mono;
/***
* 动态配置getway路由(基于数据库形式),可在项目启动成功后执行
*
* @author Administrator
*
*/
@Component
public class GetWayService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
/***
* 加载所有路由
*/
@Async
public void laodAllRoute() {
// 从数据库中获取路由信息
List<GateWay> gateWays = new ArrayList<>();
if (gateWays != null && gateWays.size() > 0) {
for (GateWay gateWay : gateWays) {
loadRoute(gateWay);
}
}
}
/***
* 加载路由策略
*
* @param gateWayEntity
* @return
*/
public String loadRoute(GateWay gateWayEntity) {
RouteDefinition definition = new RouteDefinition();
Map<String, String> predicateParams = new HashMap<>(8);
PredicateDefinition predicate = new PredicateDefinition();
FilterDefinition filterDefinition = new FilterDefinition();
Map<String, String> filterParams = new HashMap<>(8);
// 如果配置路由type为0的话 则从注册中心获取服务
URI uri = null;
if (gateWayEntity.getRouteType().equals("0")) {
uri = uri = UriComponentsBuilder.fromUriString("lb://" + gateWayEntity.getRouteUrl() + "/").build().toUri();
} else {
uri = UriComponentsBuilder.fromHttpUrl(gateWayEntity.getRouteUrl()).build().toUri();
}
// 定义的路由唯一的id
definition.setId(gateWayEntity.getRouteId());
predicate.setName("Path");
// 路由转发地址
predicateParams.put("pattern", gateWayEntity.getRoutePattern());
predicate.setArgs(predicateParams);
// 名称是固定的, 路径去前缀
filterDefinition.setName("StripPrefix");
filterParams.put("_genkey_0", "1");
filterDefinition.setArgs(filterParams);
definition.setPredicates(Arrays.asList(predicate));
definition.setFilters(Arrays.asList(filterDefinition));
definition.setUri(uri);
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "路由加载完成";
}
}
GateWay类
package com.huahailong.dynamicConfig.domain;
public class GateWay {
private Long id;
private String routeId;
private String routeName;
private String routePattern;
private String routeType;
private String routeUrl;
}
maven配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.5</version>
</dependency>
</dependencies>