< ! --  网关 -- > < dependency> < groupId> . springframework. cloud< / groupId> < artifactId> - cloud- starter- gateway< / artifactId> < / dependency> 
		< ! -- Spring  boot 依赖( 微服务基础) -- > < dependency> < groupId> . springframework. boot< / groupId> < artifactId> - boot- starter< / artifactId> < ! -- 使用exclusions标签来标明要排除的包-- > < ! -- 排除logback-- > < exclusions> < exclusion> < groupId> . springframework. boot< / groupId> < artifactId> - boot- starter- logging< / artifactId> < / exclusion> < / exclusions> < / dependency> < ! -- Web  服务相关-- > < dependency> < groupId> . springframework. boot< / groupId> < artifactId> - boot- starter- web< / artifactId> < / dependency> < ! --  生成配置元数据,比如你平常在yml文件里面配置 -- > < dependency> < groupId> . springframework. boot< / groupId> < artifactId> - boot- configuration- processor< / artifactId> < optional> true < / optional> < / dependency> < ! -- 单元测试依赖, 子工程中需要单元测试时, 不需要再次引入此依赖了-- > < dependency> < groupId> . springframework. boot< / groupId> < artifactId> - boot- starter- test< / artifactId> < scope> < / scope> < exclusions> < exclusion> < groupId> . junit. vintage< / groupId> < artifactId> - vintage- engine< / artifactId> < / exclusion> < / exclusions> < / dependency> < ! -- bootstrap 相关-- > < ! -- SpringBoot2 .4 . x之后默认不加载bootstrap. yml文件,需要在pom里加上依赖-- > < dependency> < groupId> . springframework. cloud< / groupId> < artifactId> - cloud- starter- bootstrap< / artifactId> < version> 4.0 .0 < / version> < / dependency> < ! -- 服务的注册和发现-- > < dependency> < groupId> . alibaba. cloud< / groupId> < artifactId> - cloud- starter- alibaba- nacos- config< / artifactId> < / dependency> < dependency> < groupId> . alibaba. cloud< / groupId> < artifactId> - cloud- starter- alibaba- nacos- discovery< / artifactId> < / dependency> < ! -- lombok 依赖, 子工程中假如需要lombok, 不需要再引入-- > < ! --  https: / / mvnrepository. com/ artifact/ org. projectlombok/ lombok -- > < dependency> < groupId> . projectlombok< / groupId> < artifactId> < / artifactId> < version> 1.18 .30 < / version> < scope> < / scope> < / dependency> < ! --  网关 -- > < dependency> < groupId> . springframework. cloud< / groupId> < artifactId> - cloud- starter- gateway< / artifactId> < / dependency> 
server: port:  9999 tomcat: max- http- form- post- size:  - 1 max- threads:  500 min- spare- threads:  50 servlet: context- path:  / 
spring: main: web- application- type:  reactive#当遇到同样名字的时候,是否允许覆盖注册allow- bean- definition- overriding:  true  profiles: active:  ${ SYS_ENV : }  # local: 本地,dev:测试,uat: uatapplication: name:  gateway- servicecloud: nacos: # 配置中心#config: username:  ${ NACOS_USER : nacos} password:  ${ NACOS_PASSWORD : nacos} server- addr:  ${ NACOS_IP : nacos. com} : ${ NACOS_POST : 8848 } namespace:  ${ NACOS_NAMESPACE : } file- extension:  ymlrefresh- enabled:  true override- none:  true   #本地配置优先shared- configs: -  application. ${ spring. cloud. nacos. config. file- extension}  # 配置文件名- Data  Id # 路由网关配置gateway: # 启用了自动根据服务名建立路由discovery: locator: enabled:  true lower- case - service- id:  true # 动态路由配置
config: # 动态gateway- route: # nacos 配置dataIddataId:  gateway- router# nacos服务地址server- addr:  ${ spring. cloud. nacos. config. server- addr} # 命名空间namespace:  ${ spring. cloud. nacos. config. namespace} # 账号密码username:  ${ spring. cloud. nacos. config. username} password:  ${ spring. cloud. nacos. config. password} 
 
[ { "id" :  "auth-service" , "uri" :  "lb://auth-service" , "predicates" :  [ { "args" :  { "pattern" :  "/auth-service/**" } , "name" :  "Path" } ] , "filters" :  [ { "args" :  { "parts" :  1 } , "name" :  "StripPrefix" } ] , "order" :  1 } , { "id" :  "user-service" , "uri" :  "lb://user-service" , "predicates" :  [ { "args" :  { "pattern" :  "/user-service/**" } , "name" :  "Path" } ] , "filters" :  [ { "args" :  { "parts" :  1 } , "name" :  "StripPrefix" } ] , "order" :  2 } 
] 
import  cn. hutool. core. lang.  Assert ; 
import  cn. hutool. core. util.  StrUtil ; 
import  com. alibaba. fastjson.  JSONObject ; 
import  com. alibaba. nacos. api.  NacosFactory ; 
import  com. alibaba. nacos. api. config.  ConfigService ; 
import  com. alibaba. nacos. api. config. listener.  Listener ; 
import  com. alibaba. nacos. api. exception.  NacosException ; 
import  jakarta. annotation.  PostConstruct ; 
import  lombok. extern. slf4j.  Slf4j ; 
import  org. springframework. beans. factory. annotation.  Value ; 
import  org. springframework. cloud. context. config. annotation.  RefreshScope ; 
import  org. springframework. cloud. gateway. event.  RefreshRoutesEvent ; 
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. stereotype.  Component ; 
import  reactor. core. publisher.  Mono ; import  java. util.  ArrayList ; 
import  java. util.  List ; 
import  java. util.  Properties ; 
import  java. util. concurrent.  Executor ; 
@Slf4j 
@RefreshScope 
@Component 
public  class  GatewayRouteConfig  implements  ApplicationEventPublisherAware  { private  static  final  String  PROPERTIES_SERVER_ADDR  =  "serverAddr" ; private  static  final  String  PROPERTIES_NAMESPACE  =  "namespace" ; private  static  final  String  PROPERTIES_GROUP  =  "group" ; private  static  final  String  PROPERTIES_USERNAME  =  "username" ; private  static  final  String  PROPERTIES_PASSWORD  =  "password" ; @Value ( "${config.gateway-route.dataId:gateway-router}" ) private  String  dataId =  "gateway-routes" ; @Value ( "${config.gateway-route.group:DEFAULT_GROUP}" ) private  String  group =  "DEFAULT_GROUP" ; @Value ( "${config.gateway-route.server-addr}" ) private  String  serverAddr; @Value ( "${config.gateway-route.namespace}" ) private  String  namespace; @Value ( "${config.gateway-route.username}" ) private  String  username; @Value ( "${config.gateway-route.password}" ) private  String  password; private  static  final  List < String > ROUTE_LIST  =  new  ArrayList < > ( ) ; private  final  RouteDefinitionWriter  routeDefinitionWriter; private  ApplicationEventPublisher  applicationEventPublisher; public  GatewayRouteConfig ( RouteDefinitionWriter  routeDefinitionWriter)  { this . routeDefinitionWriter =  routeDefinitionWriter; } @Override public  void  setApplicationEventPublisher ( ApplicationEventPublisher  applicationEventPublisher)  { this . applicationEventPublisher =  applicationEventPublisher; } @PostConstruct public  void  loadRouteFromNacosAndListener ( )  { try  { ConfigService  configService =  NacosFactory . createConfigService ( getProperties ( ) ) ; String  initConfigInfo =  configService. getConfig ( dataId,  group,  5000 ) ; addRouteAndPublish ( initConfigInfo) ; addListener ( configService) ; }  catch  ( NacosException  e)  { log. error ( "加载路由配置错误,详情:" ,  e) ; } } private  void  addListener ( ConfigService  cs)  throws  NacosException  { cs. addListener ( dataId,  group,  new  Listener ( )  { @Override public  void  receiveConfigInfo ( String  configInfo)  { addRouteAndPublish ( configInfo) ; } @Override public  Executor  getExecutor ( )  { return  null ; } } ) ; } private  Properties  getProperties ( )  { Assert . notBlank ( serverAddr,  "Nacos的服务地址为空了!" ) ; Properties  properties =  new  Properties ( ) ; properties. put ( PROPERTIES_SERVER_ADDR ,  serverAddr) ; if  ( StrUtil . isNotBlank ( namespace) )  { properties. put ( PROPERTIES_NAMESPACE ,  namespace) ; } if  ( StrUtil . isNotBlank ( group) )  { properties. put ( PROPERTIES_GROUP ,  group) ; } return  properties; } private  void  addRouteAndPublish ( String  configInfo)  { clearRoute ( ) ; List < RouteDefinition > =  JSONObject . parseArray ( configInfo,  RouteDefinition . class ) ; for  ( RouteDefinition  routeDefinition :  gatewayRouteDefinitions)  { routeDefinitionWriter. save ( Mono . just ( routeDefinition) ) . subscribe ( ) ; ROUTE_LIST . add ( routeDefinition. getId ( ) ) ; } this . applicationEventPublisher. publishEvent ( new  RefreshRoutesEvent ( this . routeDefinitionWriter) ) ; } private  void  clearRoute ( )  { ROUTE_LIST . forEach ( id ->  this . routeDefinitionWriter. delete ( Mono . just ( id) ) . subscribe ( ) ) ; ROUTE_LIST . clear ( ) ; } 
}