• SpringCloud核心教程 | 第二篇: 使用Intellij中的maven来快速构建Spring Cloud工程


    spring cloud简介

    spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring cloud是基于springboot的,所以需要开发中对springboot有一定的了解,如果不了解的话可以看这篇文章:2小时学会springboot。另外对于“微服务架构” 不了解的话,可以通过搜索引擎搜索“微服务架构”了解下。

    在之前的所有Spring Boot相关博文中,都会涉及Spring Boot工程的创建。而创建的方式多种多样,这里,我们可以通过Maven来手工构建或是通过脚手架等方式快速搭建。

    本文我们将介绍嵌入的Intellij中的maven工具,来快速的构建出一个基础的Spring Cloud工程。

    创建工程

    第一步: 菜单栏中选择File=>New=>Project..,我们可以看到如下图所示的创建功能窗口。然后,我们选择maven

    图片.png

    图片.png

    第二步: 点击Next,等待片刻后,我们可以看到如下图所示的工程信息窗口,在这里我们可以编辑我们想要创建的工程信息。其中,GroupId是工程的分组id,ArtifactId是模块分组id,Version是当前的版本。GroupIdArtifactIdVersion组合在一起形成一个模块的坐标

    图片.png

    第三步: 点击Next,进入最后关于工程物理存储的一些细节。最后,点击Finish就能完成工程的构建了。

    图片.png

    工程构建完成

    图片.png

    加入pom坐标

    <?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>
    
        <parent>
            <groupId>cn.zhangbox</groupId>
            <artifactId>spring-cloud-study</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        
        <groupId>cn.zhangbox.cloud.demo</groupId>
        <artifactId>cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <!-- 添加eureka支持start -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <!-- 添加eureka支持start -->
    
            <!-- 添加web支持start -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- 添加web支持end -->
    
        </dependencies>
    
        <!-- 添加cloud 依赖start -->
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Dalston.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <!-- 添加cloud 依赖end -->
    
        <!-- 添加maven构建插件start -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
        <!-- 添加maven构建插件end -->
    </project>
    

    修改YML配置

    #工程名称
    spring:
      application:
        name: cloud-demo
    #选择哪一个环境的配置
    #这里可以在每个环境配置redis,数据库(mysql),消息(kafka)等相关的组件的配置
      profiles:
        active: dev
    #配置eureka获取服务地址,这里使用的是程序员DD公开的eureka注册中心,感谢程序员DD提供的注册中心
    eureka:
      client:
        serviceUrl:
          defaultZone: http://eureka.didispace.com/eureka/
          
    #文档块区分为三个---
    ---
    server:
      port: 8081
    spring:
      profiles: dev
    #日志
    logging:
      config: classpath:log/logback.xml
      path: log/cloud-demo
    
    #文档块区分为三个---
    ---
    server:
      port: 8082
    spring:
      profiles: test
    #日志
    logging:
      config: classpath:log/logback.xml
      path: usr/cloud-demo/log/cloud-demo
    
    #文档块区分为三个---
    ---
    server:
      port: 8083
    spring:
      profiles: prod
    #日志
    logging:
      config: classpath:log/logback.xml
      path: usr/cloud-demo/log/cloud-demo
    
    

    创建日志配置文件

    在工程resources文件夹下新建文件夹log,并在该文件夹下创建logback.xml文件,加入以下配置:

    <!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
    <configuration scan="true" scanPeriod="10 seconds">
        <!--继承spring boot提供的logback配置-->
        <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
    
        <!--设置系统日志目录-->
        <property name="APP_DIR" value="cloud-demo" />
    
        <!-- 彩色日志 -->
        <!-- 彩色日志依赖的渲染类 -->
        <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
        <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
        <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
        <!-- 彩色日志格式 -->
        <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    
        <!-- 控制台输出 -->
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
            <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>debug</level>
            </filter>
        </appender>
    
        <!-- 时间滚动输出 level为 DEBUG 日志 -->
        <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 正在记录的日志文件的路径及文件名 -->
            <file>${LOG_PATH}/log_debug.log</file>
            <!--日志文件输出格式-->
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
            <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--
                    归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
                    而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
                -->
                <fileNamePattern>${LOG_PATH}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!--
                    除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
                    命名日志文件,例如log-error-2017-04-26.0.log
                -->
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>500MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--日志文件保留天数-->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <!-- 此日志文件只记录debug级别的 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>debug</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <!-- 时间滚动输出 level为 INFO 日志 -->
        <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 正在记录的日志文件的路径及文件名 -->
            <file>${LOG_PATH}/log_info.log</file>
            <!--日志文件输出格式-->
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
            <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--
                    归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
                    而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
                -->
                <fileNamePattern>${LOG_PATH}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!--
                    除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
                    命名日志文件,例如log-error-2017-04-26.0.log
                -->
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>500MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--日志文件保留天数-->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <!-- 此日志文件只记录info级别的 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>info</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <!-- 时间滚动输出 level为 WARN 日志 -->
        <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 正在记录的日志文件的路径及文件名 -->
            <file>${LOG_PATH}/log_warn.log</file>
            <!--日志文件输出格式-->
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
            <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--
                    归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
                    而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
                -->
                <fileNamePattern>${LOG_PATH}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!--
                    除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
                    命名日志文件,例如log-error-2017-04-26.0.log
                -->
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>500MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--日志文件保留天数-->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <!-- 此日志文件只记录warn级别的 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>warn</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <!-- 时间滚动输出 level为 ERROR 日志 -->
        <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 正在记录的日志文件的路径及文件名 -->
            <file>${LOG_PATH}/log_error.log</file>
            <!--日志文件输出格式-->
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
                <charset>UTF-8</charset> <!-- 此处设置字符集 -->
            </encoder>
            <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--
                    归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
                    而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
                -->
                <fileNamePattern>${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!--
                    除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
                    命名日志文件,例如log-error-2017-04-26.0.log
                -->
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>500MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--日志文件保留天数-->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <!-- 此日志文件只记录ERROR级别的 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>error</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <logger name="org.springframework.web" level="info"/>
        <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
        <logger name="cn.zhangbox.cloud" level="debug"/>
    
        <!--开发环境:打印控制台-->
        <springProfile name="dev">
            <root level="info">
                <appender-ref ref="CONSOLE" />
                <appender-ref ref="DEBUG_FILE" />
                <appender-ref ref="INFO_FILE" />
                <appender-ref ref="WARN_FILE" />
                <appender-ref ref="ERROR_FILE" />
            </root>
        </springProfile>
    
        <!--测试环境:打印控制台和输出到文件-->
        <springProfile name="test">
            <root level="info">
                <appender-ref ref="CONSOLE" />
                <appender-ref ref="INFO_FILE" />
                <appender-ref ref="WARN_FILE" />
                <appender-ref ref="ERROR_FILE" />
            </root>
        </springProfile>
    
        <!--生产环境:输出到文件-->
        <springProfile name="prod">
            <root level="error">
                <appender-ref ref="CONSOLE" />
                <appender-ref ref="DEBUG_FILE" />
                <appender-ref ref="INFO_FILE" />
                <appender-ref ref="ERROR_FILE" />
            </root>
        </springProfile>
    
    </configuration>
    

    创建Controller

    在工程java代码目录下创建controller的目录在下面创建DcController类用来测试服务是否已经注册到eureka并加入以下代码:

    @RestController
    public class DcController {
    
        @Autowired
        DiscoveryClient discoveryClient;
    
        @GetMapping("/dc")
        public String dc() {
            String services = "Services: " + discoveryClient.getServices();
            System.out.println(services);
            return services;
        }
    }
    

    创建启动类

    @EnableDiscoveryClient //使用该注解将注册服务到eureka
    @SpringBootApplication
    public class SpringCloudDemoApplication {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(
                    SpringCloudDemoApplication.class).web(true).run(args);
        }
    }
    

    控制台打印

    "C:Program FilesJavajdk1.8.0_151injava" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:51282,suspend=y,server=n -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=51281 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_151jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_151jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_151jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_151jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_151jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_151jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_151jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_151jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_151jrelibext
    ashorn.jar;C:Program FilesJavajdk1.8.0_151jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_151jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_151jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_151jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_151jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_151jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_151jrelibjce.jar;C:Program FilesJavajdk1.8.0_151jrelibjfr.jar;C:Program FilesJavajdk1.8.0_151jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_151jrelibjsse.jar;C:Program FilesJavajdk1.8.0_151jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_151jrelibplugin.jar;C:Program FilesJavajdk1.8.0_151jrelib
    esources.jar;C:Program FilesJavajdk1.8.0_151jrelib
    t.jar;C:UsersAdministratorDesktopmanagespring-cloud-studycloud-demo	argetclasses;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-starter-eureka1.3.1.RELEASEspring-cloud-starter-eureka-1.3.1.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-starter1.2.2.RELEASEspring-cloud-starter-1.2.2.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-context1.2.2.RELEASEspring-cloud-context-1.2.2.RELEASE.jar;D:开发工具
    epositoryorgspringframeworksecurityspring-security-crypto4.2.2.RELEASEspring-security-crypto-4.2.2.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-commons1.2.2.RELEASEspring-cloud-commons-1.2.2.RELEASE.jar;D:开发工具
    epositoryorgspringframeworksecurityspring-security-rsa1.0.3.RELEASEspring-security-rsa-1.0.3.RELEASE.jar;D:开发工具
    epositoryorgouncycastlecpkix-jdk15on1.55cpkix-jdk15on-1.55.jar;D:开发工具
    epositoryorgouncycastlecprov-jdk15on1.55cprov-jdk15on-1.55.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-netflix-core1.3.1.RELEASEspring-cloud-netflix-core-1.3.1.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot1.5.3.RELEASEspring-boot-1.5.3.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot-autoconfigure1.5.3.RELEASEspring-boot-autoconfigure-1.5.3.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-netflix-eureka-client1.3.1.RELEASEspring-cloud-netflix-eureka-client-1.3.1.RELEASE.jar;D:开发工具
    epositorycom
    etflixeurekaeureka-client1.6.2eureka-client-1.6.2.jar;D:开发工具
    epositoryorgcodehausjettisonjettison1.3.7jettison-1.3.7.jar;D:开发工具
    epositorystaxstax-api1.0.1stax-api-1.0.1.jar;D:开发工具
    epositorycom
    etflix
    etflix-commons
    etflix-eventbus.3.0
    etflix-eventbus-0.3.0.jar;D:开发工具
    epositorycom
    etflix
    etflix-commons
    etflix-infix.3.0
    etflix-infix-0.3.0.jar;D:开发工具
    epositorycommons-jxpathcommons-jxpath1.3commons-jxpath-1.3.jar;D:开发工具
    epositoryjoda-timejoda-time2.9.9joda-time-2.9.9.jar;D:开发工具
    epositoryorgantlrantlr-runtime3.4antlr-runtime-3.4.jar;D:开发工具
    epositoryorgantlrstringtemplate3.2.1stringtemplate-3.2.1.jar;D:开发工具
    epositoryantlrantlr2.7.7antlr-2.7.7.jar;D:开发工具
    epositorycomgooglecodegsongson2.8.0gson-2.8.0.jar;D:开发工具
    epositoryorgapachecommonscommons-math2.2commons-math-2.2.jar;D:开发工具
    epositorycom
    etflixarchaiusarchaius-core.7.4archaius-core-0.7.4.jar;D:开发工具
    epositoryjavaxws
    sjsr311-api1.1.1jsr311-api-1.1.1.jar;D:开发工具
    epositorycom
    etflixservoservo-core.10.1servo-core-0.10.1.jar;D:开发工具
    epositorycom
    etflixservoservo-internal.10.1servo-internal-0.10.1.jar;D:开发工具
    epositorycomsunjerseyjersey-core1.19.1jersey-core-1.19.1.jar;D:开发工具
    epositorycomsunjerseyjersey-client1.19.1jersey-client-1.19.1.jar;D:开发工具
    epositorycomsunjerseycontribsjersey-apache-client41.19.1jersey-apache-client4-1.19.1.jar;D:开发工具
    epositoryorgapachehttpcomponentshttpclient4.5.3httpclient-4.5.3.jar;D:开发工具
    epositoryorgapachehttpcomponentshttpcore4.4.6httpcore-4.4.6.jar;D:开发工具
    epositorycommons-codeccommons-codec1.10commons-codec-1.10.jar;D:开发工具
    epositorycomgoogleinjectguice4.1.0guice-4.1.0.jar;D:开发工具
    epositoryjavaxinjectjavax.inject1javax.inject-1.jar;D:开发工具
    epositoryaopallianceaopalliance1.0aopalliance-1.0.jar;D:开发工具
    epositorycomfasterxmljacksoncorejackson-annotations2.8.0jackson-annotations-2.8.0.jar;D:开发工具
    epositorycomfasterxmljacksoncorejackson-core2.8.8jackson-core-2.8.8.jar;D:开发工具
    epositorycom
    etflixeurekaeureka-core1.6.2eureka-core-1.6.2.jar;D:开发工具
    epositoryorgcodehauswoodstoxwoodstox-core-asl4.4.1woodstox-core-asl-4.4.1.jar;D:开发工具
    epositoryjavaxxmlstreamstax-api1.0-2stax-api-1.0-2.jar;D:开发工具
    epositoryorgcodehauswoodstoxstax2-api3.1.4stax2-api-3.1.4.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-starter-archaius1.3.1.RELEASEspring-cloud-starter-archaius-1.3.1.RELEASE.jar;D:开发工具
    epositorycommons-configurationcommons-configuration1.8commons-configuration-1.8.jar;D:开发工具
    epositorycommons-langcommons-lang2.6commons-lang-2.6.jar;D:开发工具
    epositorycomgoogleguavaguava18.0guava-18.0.jar;D:开发工具
    epositoryorgspringframeworkcloudspring-cloud-starter-ribbon1.3.1.RELEASEspring-cloud-starter-ribbon-1.3.1.RELEASE.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon2.2.2
    ibbon-2.2.2.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon-transport2.2.2
    ibbon-transport-2.2.2.jar;D:开发工具
    epositoryio
    eactivex
    xnetty-contexts.4.9
    xnetty-contexts-0.4.9.jar;D:开发工具
    epositoryio
    eactivex
    xnetty-servo.4.9
    xnetty-servo-0.4.9.jar;D:开发工具
    epositorycom
    etflixhystrixhystrix-core1.5.12hystrix-core-1.5.12.jar;D:开发工具
    epositoryorghdrhistogramHdrHistogram2.1.9HdrHistogram-2.1.9.jar;D:开发工具
    epositoryio
    eactivex
    xnetty.4.9
    xnetty-0.4.9.jar;D:开发工具
    epositoryio
    etty
    etty-codec-http4.0.27.Final
    etty-codec-http-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-codec4.0.27.Final
    etty-codec-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-handler4.0.27.Final
    etty-handler-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-transport-native-epoll4.0.27.Final
    etty-transport-native-epoll-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-common4.0.27.Final
    etty-common-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-buffer4.0.27.Final
    etty-buffer-4.0.27.Final.jar;D:开发工具
    epositoryio
    etty
    etty-transport4.0.27.Final
    etty-transport-4.0.27.Final.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon-core2.2.2
    ibbon-core-2.2.2.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon-httpclient2.2.2
    ibbon-httpclient-2.2.2.jar;D:开发工具
    epositorycommons-collectionscommons-collections3.2.2commons-collections-3.2.2.jar;D:开发工具
    epositorycom
    etflix
    etflix-commons
    etflix-commons-util.1.1
    etflix-commons-util-0.1.1.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon-loadbalancer2.2.2
    ibbon-loadbalancer-2.2.2.jar;D:开发工具
    epositorycom
    etflix
    etflix-commons
    etflix-statistics.1.1
    etflix-statistics-0.1.1.jar;D:开发工具
    epositoryio
    eactivex
    xjava1.1.10
    xjava-1.1.10.jar;D:开发工具
    epositorycom
    etflix
    ibbon
    ibbon-eureka2.2.2
    ibbon-eureka-2.2.2.jar;D:开发工具
    epositoryorgslf4jslf4j-api1.7.25slf4j-api-1.7.25.jar;D:开发工具
    epositorycom	houghtworksxstreamxstream1.4.9xstream-1.4.9.jar;D:开发工具
    epositoryxmlpullxmlpull1.1.3.1xmlpull-1.1.3.1.jar;D:开发工具
    epositoryxpp3xpp3_min1.1.4cxpp3_min-1.1.4c.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot-starter-web1.5.3.RELEASEspring-boot-starter-web-1.5.3.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot-starter1.5.3.RELEASEspring-boot-starter-1.5.3.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot-starter-logging1.5.3.RELEASEspring-boot-starter-logging-1.5.3.RELEASE.jar;D:开发工具
    epositorychqoslogbacklogback-classic1.1.11logback-classic-1.1.11.jar;D:开发工具
    epositorychqoslogbacklogback-core1.1.11logback-core-1.1.11.jar;D:开发工具
    epositoryorgslf4jjcl-over-slf4j1.7.25jcl-over-slf4j-1.7.25.jar;D:开发工具
    epositoryorgslf4jjul-to-slf4j1.7.25jul-to-slf4j-1.7.25.jar;D:开发工具
    epositoryorgslf4jlog4j-over-slf4j1.7.25log4j-over-slf4j-1.7.25.jar;D:开发工具
    epositoryorgspringframeworkspring-core4.3.8.RELEASEspring-core-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgyamlsnakeyaml1.17snakeyaml-1.17.jar;D:开发工具
    epositoryorgspringframeworkootspring-boot-starter-tomcat1.5.3.RELEASEspring-boot-starter-tomcat-1.5.3.RELEASE.jar;D:开发工具
    epositoryorgapache	omcatembed	omcat-embed-core8.5.14	omcat-embed-core-8.5.14.jar;D:开发工具
    epositoryorgapache	omcatembed	omcat-embed-el8.5.14	omcat-embed-el-8.5.14.jar;D:开发工具
    epositoryorgapache	omcatembed	omcat-embed-websocket8.5.14	omcat-embed-websocket-8.5.14.jar;D:开发工具
    epositoryorghibernatehibernate-validator5.3.5.Finalhibernate-validator-5.3.5.Final.jar;D:开发工具
    epositoryjavaxvalidationvalidation-api1.1.0.Finalvalidation-api-1.1.0.Final.jar;D:开发工具
    epositoryorgjbossloggingjboss-logging3.3.1.Finaljboss-logging-3.3.1.Final.jar;D:开发工具
    epositorycomfasterxmlclassmate1.3.3classmate-1.3.3.jar;D:开发工具
    epositorycomfasterxmljacksoncorejackson-databind2.8.8jackson-databind-2.8.8.jar;D:开发工具
    epositoryorgspringframeworkspring-web4.3.8.RELEASEspring-web-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkspring-aop4.3.8.RELEASEspring-aop-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkspring-beans4.3.8.RELEASEspring-beans-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkspring-context4.3.8.RELEASEspring-context-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkspring-webmvc4.3.8.RELEASEspring-webmvc-4.3.8.RELEASE.jar;D:开发工具
    epositoryorgspringframeworkspring-expression4.3.8.RELEASEspring-expression-4.3.8.RELEASE.jar;C:Program FilesJetBrainsIntelliJ IDEA 2017.2.6libidea_rt.jar" cn.zhangbox.cloud.SpringCloudDemoApplication
    Connected to the target VM, address: '127.0.0.1:51282', transport: 'socket'
    2018-07-13 17:13:30.459  INFO 8104 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4416d64f: startup date [Fri Jul 13 17:13:30 GMT+08:00 2018]; root of context hierarchy
    2018-07-13 17:13:30.983  INFO 8104 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-07-13 17:13:31.057  INFO 8104 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$52bfc5ff] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    
      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v1.5.3.RELEASE)
    
    2018-07-13 17:13:31.835  INFO 8104 --- [           main] c.z.cloud.SpringCloudDemoApplication     : The following profiles are active: dev
    2018-07-13 17:13:31.850  INFO 8104 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@160396db: startup date [Fri Jul 13 17:13:31 GMT+08:00 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@4416d64f
    2018-07-13 17:13:32.470  INFO 8104 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=61cde5fe-b448-3350-a5e4-3ab1b78398ff
    2018-07-13 17:13:32.489  INFO 8104 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-07-13 17:13:32.553  INFO 8104 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$52bfc5ff] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2018-07-13 17:13:33.018  INFO 8104 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8081 (http)
    2018-07-13 17:13:33.032  INFO 8104 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
    2018-07-13 17:13:33.034  INFO 8104 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.14
    2018-07-13 17:13:33.199  INFO 8104 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2018-07-13 17:13:33.199  INFO 8104 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1349 ms
    2018-07-13 17:13:33.345  INFO 8104 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
    2018-07-13 17:13:33.350  INFO 8104 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
    2018-07-13 17:13:33.351  INFO 8104 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
    2018-07-13 17:13:33.351  INFO 8104 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
    2018-07-13 17:13:33.351  INFO 8104 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
    2018-07-13 17:13:34.025  INFO 8104 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@160396db: startup date [Fri Jul 13 17:13:31 GMT+08:00 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@4416d64f
    2018-07-13 17:13:34.094  INFO 8104 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/dc],methods=[GET]}" onto public java.lang.String cn.zhangbox.cloud.controller.DcController.dc()
    2018-07-13 17:13:34.098  INFO 8104 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
    2018-07-13 17:13:34.099  INFO 8104 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
    2018-07-13 17:13:34.142  INFO 8104 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2018-07-13 17:13:34.142  INFO 8104 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2018-07-13 17:13:34.189  INFO 8104 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2018-07-13 17:13:34.555  WARN 8104 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
    2018-07-13 17:13:34.555  INFO 8104 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
    2018-07-13 17:13:34.561  WARN 8104 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
    2018-07-13 17:13:34.561  INFO 8104 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
    2018-07-13 17:13:34.697  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    2018-07-13 17:13:34.707  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'environmentManager' has been autodetected for JMX exposure
    2018-07-13 17:13:34.708  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
    2018-07-13 17:13:34.709  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshScope' has been autodetected for JMX exposure
    2018-07-13 17:13:34.711  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
    2018-07-13 17:13:34.726  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
    2018-07-13 17:13:34.739  INFO 8104 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=160396db,type=ConfigurationPropertiesRebinder]
    2018-07-13 17:13:34.881  INFO 8104 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
    2018-07-13 17:13:34.890  INFO 8104 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
    2018-07-13 17:13:35.012  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
    2018-07-13 17:13:35.418  INFO 8104 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON encoding codec LegacyJacksonJson
    2018-07-13 17:13:35.418  INFO 8104 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON decoding codec LegacyJacksonJson
    2018-07-13 17:13:35.554  INFO 8104 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML encoding codec XStreamXml
    2018-07-13 17:13:35.554  INFO 8104 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML decoding codec XStreamXml
    2018-07-13 17:13:35.935  INFO 8104 --- [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
    2018-07-13 17:13:36.021  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
    2018-07-13 17:13:36.022  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
    2018-07-13 17:13:36.022  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
    2018-07-13 17:13:36.022  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
    2018-07-13 17:13:36.022  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
    2018-07-13 17:13:36.023  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
    2018-07-13 17:13:36.023  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
    2018-07-13 17:13:36.260  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
    2018-07-13 17:13:36.262  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Starting heartbeat executor: renew interval is: 30
    2018-07-13 17:13:36.266  INFO 8104 --- [           main] c.n.discovery.InstanceInfoReplicator     : InstanceInfoReplicator onDemand update allowed rate per min is 4
    2018-07-13 17:13:36.269  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1531473216269 with initial instances count: 26
    2018-07-13 17:13:36.288  INFO 8104 --- [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application cloud-demo with eureka with status UP
    2018-07-13 17:13:36.289  INFO 8104 --- [           main] com.netflix.discovery.DiscoveryClient    : Saw local status change event StatusChangeEvent [timestamp=1531473216289, current=UP, previous=STARTING]
    2018-07-13 17:13:36.291  INFO 8104 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_CLOUD-DEMO/windows10.microdone.cn:cloud-demo:8081: registering service...
    2018-07-13 17:13:36.342  INFO 8104 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_CLOUD-DEMO/windows10.microdone.cn:cloud-demo:8081 - registration status: 204
    2018-07-13 17:13:36.360  INFO 8104 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
    2018-07-13 17:13:36.360  INFO 8104 --- [           main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8081
    2018-07-13 17:13:36.364  INFO 8104 --- [           main] c.z.cloud.SpringCloudDemoApplication     : Started SpringCloudDemoApplication in 6.85 seconds (JVM running for 8.116)
    2018-07-13 17:13:45.808  INFO 8104 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
    2018-07-13 17:13:45.809  INFO 8104 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
    2018-07-13 17:13:45.838  INFO 8104 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 29 ms
    Services: [zcs-apps-gateway, mystore-user-jwt, eureka-feign-client, scca-server-all-in-one, oms-system, zcs-apps-config, apollo-adminservice, staryun-product, tm-web, gateway-server, config-server, apollo-configservice, base-service, hd-cloud-boss, wm-svr-gateway, tm-admin, gzepro-manage-service, cva, zcs-jzsy-ops-new, x-cbiz, hd-config-server, wm-app-basicmanager, cloud-demo, wm-app-authserver, service-configuration, api-gateway]
    

    eureka管控台正常显示

    浏览器输入地址:
    http://eureka.didispace.com/
    看到服务已经成功注册。

    图片.png

    当然,我们也可以通过直接访问eureka-client服务提供的/dc接口来获取当前的服务清单,只需要访问:http://localhost:2001/dc,我们可以得到如下输出返回:

    Services: [zcs-apps-gateway, mystore-user-jwt, eureka-feign-client, scca-server-all-in-one, oms-system, zcs-apps-config, apollo-adminservice, staryun-product, tm-web, gateway-server, config-server, apollo-configservice, base-service, hd-cloud-boss, wm-svr-gateway, tm-admin, gzepro-manage-service, cva, zcs-jzsy-ops-new, x-cbiz, hd-config-server, wm-app-basicmanager, cloud-demo, wm-app-authserver, service-configuration, api-gateway]
    

    可以看到cloud-demo包含在里面。至此maven快速构建cloud项目并启动测试已全部完成。

    源码地址:

    SpringCloud使用Intellij中的maven来快速构建Spring Cloud工程



    作者:星缘1314
    链接:https://www.jianshu.com/p/8700851622ab
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    关注「编程微刊」公众号 ,在微信后台回复「领取资源」,获取IT资源300G干货大全。

    公众号回复“1”,拉你进程序员技术讨论群.

  • 相关阅读:
    <mvc:annotation-driven>新增标签
    关于Spring中的<context:annotation-config/>配置
    <mvc:default-servlet-handler/>的作用
    各种WEB服务器自带的默认Servlet名称
    常用邮件协议
    vue-cli 脚手架项目简介(一)
    CSS3的transition和transform
    Spring配置文件<context:property-placeholder>标签使用漫谈
    使用Spring JDBCTemplate简化JDBC的操作
    技术探索不易
  • 原文地址:https://www.cnblogs.com/wangting888/p/9701395.html
Copyright © 2020-2023  润新知