417.98368241.js 42.7 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1
(window.webpackJsonp=window.webpackJsonp||[]).push([[417],{851:function(e,r,t){"use strict";t.r(r);var a=t(56),i=Object(a.a)({},(function(){var e=this,r=e.$createElement,t=e._self._c||r;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"spring-cloud断路器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spring-cloud断路器"}},[e._v("#")]),e._v(" Spring Cloud断路器")]),e._v(" "),t("p",[t("strong",[e._v("2.1.1")])]),e._v(" "),t("h2",{attrs:{id:"_1-使用文档"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-使用文档"}},[e._v("#")]),e._v(" 1.使用文档")]),e._v(" "),t("p",[e._v("Spring Cloud Circuitbreaker 项目包含 Resilience4J 和 Spring Retry 的实现。在 Spring cloud circuitbreaker 中实现的 API 是在 Spring cloud commons 中实现的。这些 API 的使用文档位于"),t("a",{attrs:{href:"https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-circuit-breaker",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Commons documentation"),t("OutboundLink")],1),e._v("中。")]),e._v(" "),t("h3",{attrs:{id:"_1-1-配置弹性-4j-断路器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-配置弹性-4j-断路器"}},[e._v("#")]),e._v(" 1.1.配置弹性 4J 断路器")]),e._v(" "),t("h4",{attrs:{id:"_1-1-1-初学者"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-1-初学者"}},[e._v("#")]),e._v(" 1.1.1.初学者")]),e._v(" "),t("p",[e._v("弹性 4J 实现有两个启动器,一个用于反应性应用程序,另一个用于非反应性应用程序。")]),e._v(" "),t("ul",[t("li",[t("p",[t("code",[e._v("org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j")]),e._v("-无反应应用")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j")]),e._v("-反应性应用")])])]),e._v(" "),t("h4",{attrs:{id:"_1-1-2-自动配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-2-自动配置"}},[e._v("#")]),e._v(" 1.1.2.自动配置")]),e._v(" "),t("p",[e._v("通过将"),t("code",[e._v("spring.cloud.circuitbreaker.resilience4j.enabled")]),e._v("设置为"),t("code",[e._v("false")]),e._v(",可以禁用 Resilience4j 自动配置。")]),e._v(" "),t("h4",{attrs:{id:"_1-1-3-默认配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-3-默认配置"}},[e._v("#")]),e._v(" 1.1.3.默认配置")]),e._v(" "),t("p",[e._v("要为你的所有断路器提供默认配置,请创建一个"),t("code",[e._v("Customize")]),e._v(" Bean,它传递一个"),t("code",[e._v("Resilience4JCircuitBreakerFactory")]),e._v(""),t("code",[e._v("ReactiveResilience4JCircuitBreakerFactory")]),e._v(""),t("code",[e._v("configureDefault")]),e._v("方法可用于提供默认配置。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@Bean\npublic Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {\n    return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)\n            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build())\n            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())\n            .build());\n}\n")])])]),t("h5",{attrs:{id:"反应式示例"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#反应式示例"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#reactive-example"}}),t("a",{attrs:{href:"#reactive-example"}},[e._v("反应式示例")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@Bean\npublic Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {\n    return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)\n            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())\n            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build());\n}\n")])])]),t("h4",{attrs:{id:"_1-1-4-特定断路器配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-4-特定断路器配置"}},[e._v("#")]),e._v(" 1.1.4.特定断路器配置")]),e._v(" "),t("p",[e._v("与提供默认配置类似,你可以创建一个"),t("code",[e._v("Customize")]),e._v(" Bean 这是传递一个"),t("code",[e._v("Resilience4JCircuitBreakerFactory")]),e._v(""),t("code",[e._v("ReactiveResilience4JCircuitBreakerFactory")]),e._v("")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {\n    return factory -> factory.configure(builder -> builder.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())\n            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build()), "slow");\n}\n')])])]),t("p",[e._v("除了配置被创建的断路器之外,你还可以在断路器被创建之后但在断路器被返回给调用者之前自定义断路器。要做到这一点,你可以使用"),t("code",[e._v("addCircuitBreakerCustomizer")]),e._v("方法。这对于将事件处理程序添加到 Resilience4J 断路器非常有用。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {\n    return factory -> factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()\n    .onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");\n}\n')])])]),t("h5",{attrs:{id:"反应式示例-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#反应式示例-2"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#reactive-example-2"}}),t("a",{attrs:{href:"#reactive-example-2"}},[e._v("反应式示例")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<ReactiveResilience4JCircuitBreakerFactory> slowCustomizer() {\n    return factory -> {\n        factory.configure(builder -> builder\n        .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build())\n        .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()), "slow", "slowflux");\n        factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()\n            .onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");\n     };\n}\n')])])]),t("h4",{attrs:{id:"_1-1-5-断路器特性配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-5-断路器特性配置"}},[e._v("#")]),e._v(" 1.1.5.断路器特性配置")]),e._v(" "),t("p",[e._v("你可以在应用程序的配置属性文件中配置"),t("code",[e._v("CircuitBreaker")]),e._v(""),t("code",[e._v("TimeLimiter")]),e._v("实例。属性配置比 Java"),t("code",[e._v("Customizer")]),e._v("配置具有更高的优先级。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("resilience4j.circuitbreaker:\n instances:\n     backendA:\n         registerHealthIndicator: true\n         slidingWindowSize: 100\n     backendB:\n         registerHealthIndicator: true\n         slidingWindowSize: 10\n         permittedNumberOfCallsInHalfOpenState: 3\n         slidingWindowType: TIME_BASED\n         recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate\n\nresilience4j.timelimiter:\n instances:\n     backendA:\n         timeoutDuration: 2s\n         cancelRunningFuture: true\n     backendB:\n         timeoutDuration: 1s\n         cancelRunningFuture: false\n")])])]),t("p",[e._v("有关 Resilience4j 属性配置的更多信息,请参见"),t("a",{attrs:{href:"https://resilience4j.readme.io/docs/getting-started-3#configuration",target:"_blank",rel:"noopener noreferrer"}},[e._v("Resilience4J Spring Boot 2 Configuration"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h4",{attrs:{id:"_1-1-6-舱壁模式支撑"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-6-舱壁模式支撑"}},[e._v("#")]),e._v(" 1.1.6.舱壁模式支撑")]),e._v(" "),t("p",[e._v("如果"),t("code",[e._v("resilience4j-bulkhead")]),e._v("在 Classpath 上, Spring Cloud Circuitbreaker 将用 Resilience4J 隔板包装所有方法。你可以通过将"),t("code",[e._v("spring.cloud.circuitbreaker.bulkhead.resilience4j.enabled")]),e._v("设置为"),t("code",[e._v("false")]),e._v("来禁用 Resilience4J 舱壁。")]),e._v(" "),t("p",[e._v("Spring Cloud Circuitbreaker Resilience4J 提供了两种舱壁模式的实现方式:")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("使用信号量的"),t("code",[e._v("SemaphoreBulkhead")])])]),e._v(" "),t("li",[t("p",[e._v("使用有界队列和固定线程池的"),t("code",[e._v("FixedThreadPoolBulkhead")]),e._v("")])])]),e._v(" "),t("p",[e._v("默认情况下, Spring Cloud Circuitbreaker Resilience4j 使用"),t("code",[e._v("FixedThreadPoolBulkhead")]),e._v("。有关舱壁模式实现的更多信息,请参见"),t("a",{attrs:{href:"https://resilience4j.readme.io/docs/bulkhead",target:"_blank",rel:"noopener noreferrer"}},[e._v("弹性 4J 舱壁"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("p",[t("code",[e._v("Customizer<Resilience4jBulkheadProvider>")]),e._v("可用于提供默认的"),t("code",[e._v("Bulkhead")]),e._v(""),t("code",[e._v("ThreadPoolBulkhead")]),e._v("配置。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@Bean\npublic Customizer<Resilience4jBulkheadProvider> defaultBulkheadCustomizer() {\n    return provider -> provider.configureDefault(id -> new Resilience4jBulkheadConfigurationBuilder()\n        .bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(4).build())\n        .threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.custom().coreThreadPoolSize(1).maxThreadPoolSize(1).build())\n        .build()\n);\n}\n")])])]),t("h4",{attrs:{id:"_1-1-7-特定舱壁结构"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-7-特定舱壁结构"}},[e._v("#")]),e._v(" 1.1.7.特定舱壁结构")]),e._v(" "),t("p",[e._v("与证明默认的“bulkhead”或“threadpoolbulkhead”配置类似,你可以创建"),t("code",[e._v("Customize")]),e._v(" Bean 这传递了一个"),t("code",[e._v("Resilience4jBulkheadProvider")]),e._v("")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<Resilience4jBulkheadProvider> slowBulkheadProviderCustomizer() {\n    return provider -> provider.configure(builder -> builder\n        .bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(1).build())\n        .threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.ofDefaults()), "slowBulkhead");\n}\n')])])]),t("p",[e._v("除了配置所创建的舱壁之外,你还可以在舱壁和线程池的舱壁被创建之后但在它们被返回给调用方之前自定义它们。要做到这一点,你可以使用"),t("code",[e._v("addBulkheadCustomizer")]),e._v(""),t("code",[e._v("addThreadPoolBulkheadCustomizer")]),e._v("方法。")]),e._v(" "),t("h5",{attrs:{id:"舱壁示例"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#舱壁示例"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#bulkhead-example"}}),t("a",{attrs:{href:"#bulkhead-example"}},[e._v("舱壁示例")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<Resilience4jBulkheadProvider> customizer() {\n    return provider -> provider.addBulkheadCustomizer(bulkhead -> bulkhead.getEventPublisher()\n        .onCallRejected(slowRejectedConsumer)\n        .onCallFinished(slowFinishedConsumer), "slowBulkhead");\n}\n')])])]),t("h5",{attrs:{id:"线程池隔板示例"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#线程池隔板示例"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#thread-pool-bulkhead-example"}}),t("a",{attrs:{href:"#thread-pool-bulkhead-example"}},[e._v("线程池隔板示例")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<Resilience4jBulkheadProvider> slowThreadPoolBulkheadCustomizer() {\n    return provider -> provider.addThreadPoolBulkheadCustomizer(threadPoolBulkhead -> threadPoolBulkhead.getEventPublisher()\n        .onCallRejected(slowThreadPoolRejectedConsumer)\n        .onCallFinished(slowThreadPoolFinishedConsumer), "slowThreadPoolBulkhead");\n}\n')])])]),t("h4",{attrs:{id:"_1-1-8-舱壁属性配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-8-舱壁属性配置"}},[e._v("#")]),e._v(" 1.1.8.舱壁属性配置")]),e._v(" "),t("p",[e._v("你可以在应用程序的配置属性文件中配置 ThreadPoolBulkhead 和 SemaphoreBulkhead 实例。属性配置比 Java"),t("code",[e._v("Customizer")]),e._v("配置具有更高的优先级。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("resilience4j.thread-pool-bulkhead:\n    instances:\n        backendA:\n            maxThreadPoolSize: 1\n            coreThreadPoolSize: 1\nresilience4j.bulkhead:\n    instances:\n        backendB:\n            maxConcurrentCalls: 10\n")])])]),t("p",[e._v("有关 Resilience4j 属性配置的更多信息,请参见"),t("a",{attrs:{href:"https://resilience4j.readme.io/docs/getting-started-3#configuration",target:"_blank",rel:"noopener noreferrer"}},[e._v("Resilience4J Spring Boot 2 Configuration"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h4",{attrs:{id:"_1-1-9-收集指标"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-9-收集指标"}},[e._v("#")]),e._v(" 1.1.9.收集指标")]),e._v(" "),t("p",[e._v("Spring Cloud断路器弹性 4j 包括自动配置以设置度量收集,只要正确的依赖关系是在 Classpath 上。要启用度量集合,必须包括"),t("code",[e._v("org.springframework.boot:spring-boot-starter-actuator")]),e._v(""),t("code",[e._v("io.github.resilience4j:resilience4j-micrometer")]),e._v("。有关存在这些依赖关系时产生的度量的更多信息,请参见"),t("a",{attrs:{href:"https://resilience4j.readme.io/docs/micrometer",target:"_blank",rel:"noopener noreferrer"}},[e._v("复原力 4J 文档"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("你不必直接包含"),t("code",[e._v("micrometer-core")]),e._v(",因为它是由"),t("code",[e._v("spring-boot-starter-actuator")]),e._v("引入的")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h3",{attrs:{id:"_1-2-configuring-spring-retry-circuit-breakers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-configuring-spring-retry-circuit-breakers"}},[e._v("#")]),e._v(" 1.2. Configuring Spring Retry Circuit Breakers")]),e._v(" "),t("p",[e._v("Spring Retry 为 Spring 应用程序提供声明性重试支持。该项目的一个子集包括实现断路器功能的能力。 Spring Retry 通过它的["),t("code",[e._v("CircuitBreakerRetryPolicy")]),e._v('](https://github.com/ Spring-projects/ Spring-retry/blob/master/SRC/main/java/org/springframework/retry/policy/circuitbreakerretrygt.java)和<<r="134"/>的组合提供了一个断路器实现。所有使用 Spring 重试创建的断路器都将使用'),t("code",[e._v("CircuitBreakerRetryPolicy")]),e._v("和["),t("code",[e._v("DefaultRetryState")]),e._v("](https://github.com/ Spring-projects/ Spring-retry/blob/master/SRC/main/java/org/springframework/retry/support/defaultrystate.java)创建。这两个类都可以使用"),t("code",[e._v("SpringRetryConfigBuilder")]),e._v("进行配置。")]),e._v(" "),t("h4",{attrs:{id:"_1-2-1-默认配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-1-默认配置"}},[e._v("#")]),e._v(" 1.2.1.默认配置")]),e._v(" "),t("p",[e._v("要为你的所有断路器提供默认配置,请创建一个"),t("code",[e._v("Customize")]),e._v(" Bean,传递一个"),t("code",[e._v("SpringRetryCircuitBreakerFactory")]),e._v(""),t("code",[e._v("configureDefault")]),e._v("方法可用于提供默认配置。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@Bean\npublic Customizer<SpringRetryCircuitBreakerFactory> defaultCustomizer() {\n    return factory -> factory.configureDefault(id -> new SpringRetryConfigBuilder(id)\n        .retryPolicy(new TimeoutRetryPolicy()).build());\n}\n")])])]),t("h4",{attrs:{id:"_1-2-2-特定断路器配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-2-特定断路器配置"}},[e._v("#")]),e._v(" 1.2.2.特定断路器配置")]),e._v(" "),t("p",[e._v("与提供默认配置类似,你可以创建"),t("code",[e._v("Customize")]),e._v(" Bean 这是传递的"),t("code",[e._v("SpringRetryCircuitBreakerFactory")]),e._v("")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Bean\npublic Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {\n    return factory -> factory.configure(builder -> builder.retryPolicy(new SimpleRetryPolicy(1)).build(), "slow");\n}\n')])])]),t("p",[e._v("除了配置被创建的断路器之外,你还可以在断路器被创建之后但在断路器被返回给调用者之前自定义断路器。要做到这一点,你可以使用"),t("code",[e._v("addRetryTemplateCustomizers")]),e._v("方法。这对于将事件处理程序添加到"),t("code",[e._v("RetryTemplate")]),e._v("非常有用。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@Bean\npublic Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {\n    return factory -> factory.addRetryTemplateCustomizers(retryTemplate -> retryTemplate.registerListener(new RetryListener() {\n\n        @Override\n        public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {\n            return false;\n        }\n\n        @Override\n        public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {\n\n        }\n\n        @Override\n        public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {\n\n        }\n    }));\n}\n")])])]),t("h2",{attrs:{id:"_2-建筑物"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-建筑物"}},[e._v("#")]),e._v(" 2.建筑物")]),e._v(" "),t("h3",{attrs:{id:"_2-1-基本编译和测试"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-基本编译和测试"}},[e._v("#")]),e._v(" 2.1.基本编译和测试")]),e._v(" "),t("p",[e._v("要构建源代码,你需要安装 JDK17。")]),e._v(" "),t("p",[e._v("Spring Cloud 在大多数与构建相关的活动中使用 Maven,你应该能够通过克隆感兴趣的项目并键入来很快地开始工作。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ ./mvnw install\n")])])]),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("你也可以自己安装 Maven(>=3.3.3),并在下面的示例中运行"),t("code",[e._v("mvn")]),e._v("命令"),t("br"),e._v("来代替"),t("code",[e._v("./mvnw")]),e._v("。如果你这样做,那么如果你的本地 Maven 设置不"),t("br"),e._v("包含 Spring 预发布工件的存储库声明,那么你可能还需要添加"),t("code",[e._v("-P spring")]),e._v("")])])]),e._v(" "),t("tbody")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("请注意,你可能需要通过使用"),t("br"),e._v("设置"),t("code",[e._v("-Xmx512m -XX:MaxPermSize=128m")]),e._v("这样的值的"),t("code",[e._v("MAVEN_OPTS")]),e._v("环境变量来增加 Maven 可用的"),t("br"),e._v("内存量。我们试图在"),t("br"),e._v(""),t("code",[e._v(".mvn")]),e._v("配置中覆盖此内容,因此,如果你发现必须这样做才能使"),t("br"),e._v("构建成功,请举出一张票来将设置添加到"),t("br"),e._v("源代码控制中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("p",[e._v("需要中间件(即 Redis)进行测试的项目通常需要安装并运行[Docker]("),t("a",{attrs:{href:"https://www.docker.com/get-started",target:"_blank",rel:"noopener noreferrer"}},[e._v("WWW.docker.com/get-started"),t("OutboundLink")],1),e._v(")的本地实例。")]),e._v(" "),t("h3",{attrs:{id:"_2-2-文件"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-文件"}},[e._v("#")]),e._v(" 2.2.文件")]),e._v(" "),t("p",[e._v("Spring-cloud-build 模块具有一个“DOCS”配置文件,如果你将其打开,它将尝试从"),t("code",[e._v("src/main/asciidoc")]),e._v("构建 ASCIIDoc 源。作为该过程的一部分,它将寻找"),t("code",[e._v("README.adoc")]),e._v(",并通过加载所有的包含来处理它,但不是解析或呈现它,只是将其复制到"),t("code",[e._v("${main.basedir}")]),e._v("(默认为"),t("code",[e._v("$/tmp/releaser-1645116950347-0/spring-cloud-circuitbreaker/docs")]),e._v(",即项目的根)。如果 README 中有任何更改,那么在构建 Maven 之后,它将在正确的位置显示为经过修改的文件。只要承诺并推动改变就行了。")]),e._v(" "),t("h3",{attrs:{id:"_2-3-使用代码"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-使用代码"}},[e._v("#")]),e._v(" 2.3.使用代码")]),e._v(" "),t("p",[e._v("如果你没有 IDE 偏好,我们建议你在使用代码时使用"),t("a",{attrs:{href:"https://www.springsource.com/developer/sts",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Tools Suite"),t("OutboundLink")],1),e._v(""),t("a",{attrs:{href:"https://eclipse.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("Eclipse"),t("OutboundLink")],1),e._v("。我们使用"),t("a",{attrs:{href:"https://eclipse.org/m2e/",target:"_blank",rel:"noopener noreferrer"}},[e._v("m2eclipse"),t("OutboundLink")],1),e._v("Eclipse 插件来提供 Maven 支持。其他 IDE 和工具也应该在没有问题的情况下工作,只要它们使用 Maven 3.3.3 或更好。")]),e._v(" "),t("h4",{attrs:{id:"_2-3-1-activate-the-spring-maven-profile"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-1-activate-the-spring-maven-profile"}},[e._v("#")]),e._v(" 2.3.1. Activate the Spring Maven profile")]),e._v(" "),t("p",[e._v("Spring Cloud项目需要激活“ Spring” Maven 配置文件,以解析 Spring 里程碑和快照存储库。使用你首选的 IDE 将此配置文件设置为活动的,否则你可能会遇到构建错误。")]),e._v(" "),t("h4",{attrs:{id:"_2-3-2-用-m2eclipse-导入到-eclipse-中"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-2-用-m2eclipse-导入到-eclipse-中"}},[e._v("#")]),e._v(" 2.3.2.用 M2Eclipse 导入到 Eclipse 中")]),e._v(" "),t("p",[e._v("在使用 Eclipse 时,我们推荐"),t("a",{attrs:{href:"https://eclipse.org/m2e/",target:"_blank",rel:"noopener noreferrer"}},[e._v("m2eclipse"),t("OutboundLink")],1),e._v("Eclipse 插件。如果你还没有安装 M2Eclipse,它可以从“Eclipse 市场”获得。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("较早版本的 M2E 不支持 Maven 3.3,因此,一旦"),t("br"),e._v("项目导入到 Eclipse 中,你还需要告诉"),t("br"),e._v("M2Eclipse 为项目使用正确的配置文件。如果你"),t("br"),e._v("在项目中看到许多与 POM 相关的错误,请检查"),t("br"),e._v("是否有最新的安装。如果你不能升级 M2E,"),t("br"),e._v("将“ Spring”配置文件添加到你的"),t("code",[e._v("settings.xml")]),e._v("。或者,你可以"),t("br"),e._v("将存储库设置从父"),t("br"),e._v(" POM 的“ Spring”配置文件复制到你的"),t("code",[e._v("settings.xml")]),e._v("中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h4",{attrs:{id:"_2-3-3-在没有-m2eclipse-的情况下导入-eclipse"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-3-在没有-m2eclipse-的情况下导入-eclipse"}},[e._v("#")]),e._v(" 2.3.3.在没有 M2Eclipse 的情况下导入 Eclipse")]),e._v(" "),t("p",[e._v("如果不喜欢使用 M2Eclipse,可以使用以下命令生成 Eclipse 项目元数据:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ ./mvnw eclipse:eclipse\n")])])]),t("p",[e._v("可以通过从"),t("code",[e._v("file")]),e._v("菜单中选择"),t("code",[e._v("import existing projects")]),e._v("来导入生成的 Eclipse 项目。")]),e._v(" "),t("h2",{attrs:{id:"_3-贡献"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-贡献"}},[e._v("#")]),e._v(" 3.贡献")]),e._v(" "),t("p",[e._v("Spring Cloud 是在非限制性的 Apache2.0 许可下发布的,并遵循非常标准的 GitHub 开发流程,使用 GitHub Tracker 处理问题并将拉请求合并到 Master 中。如果你想贡献一些微不足道的东西,请不要犹豫,但要遵循下面的指导方针。")]),e._v(" "),t("h3",{attrs:{id:"_3-1-签署贡献者许可协议"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-签署贡献者许可协议"}},[e._v("#")]),e._v(" 3.1.签署贡献者许可协议")]),e._v(" "),t("p",[e._v("在我们接受一个重要的补丁或拉请求之前,我们需要你签署"),t("a",{attrs:{href:"https://cla.pivotal.io/sign/spring",target:"_blank",rel:"noopener noreferrer"}},[e._v("贡献者许可协议"),t("OutboundLink")],1),e._v("。签署贡献者协议并不会授予任何人对主库的提交权限,但这确实意味着我们可以接受你的贡献,并且如果我们接受了,你将获得作者信用。活跃的贡献者可能会被要求加入核心团队,并被赋予合并拉请求的能力。")]),e._v(" "),t("h3",{attrs:{id:"_3-2-行为守则"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-行为守则"}},[e._v("#")]),e._v(" 3.2.行为守则")]),e._v(" "),t("p",[e._v("该项目遵守贡献者契约"),t("a",{attrs:{href:"https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc",target:"_blank",rel:"noopener noreferrer"}},[e._v("行为守则"),t("OutboundLink")],1),e._v("。通过参与,你将被期望坚持这一准则。请向[[电子邮件保护]]报告不可接受的行为(/cdn-cgi/l/email-protection#4c3f3c3e25222b612f23282961232a612f232228392f380c3c253a23382d20622523)。")]),e._v(" "),t("h3",{attrs:{id:"_3-3-守则惯例和内部管理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-守则惯例和内部管理"}},[e._v("#")]),e._v(" 3.3.守则惯例和内部管理")]),e._v(" "),t("p",[e._v("这些都不是拉请求所必需的,但它们都会有所帮助。它们也可以在原始的拉请求之后但在合并之前添加。")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("使用 Spring 框架代码格式约定。如果使用 Eclipse,则可以使用"),t("code",[e._v("eclipse-code-formatter.xml")]),e._v("文件从"),t("a",{attrs:{href:"https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Build"),t("OutboundLink")],1),e._v("项目导入格式化设置。如果使用 IntelliJ,可以使用"),t("a",{attrs:{href:"https://plugins.jetbrains.com/plugin/6546",target:"_blank",rel:"noopener noreferrer"}},[e._v("Eclipse 代码格式化插件"),t("OutboundLink")],1),e._v("导入相同的文件。")])]),e._v(" "),t("li",[t("p",[e._v("确保所有新的"),t("code",[e._v(".java")]),e._v("文件都有一个简单的 Javadoc 类注释,其中至少有一个"),t("code",[e._v("@author")]),e._v("标记来标识你,并且最好至少有一个段落来说明类的用途。")])]),e._v(" "),t("li",[t("p",[e._v("将 ASF 许可标头注释添加到所有新的"),t("code",[e._v(".java")]),e._v("文件(从项目中的现有文件复制)")])]),e._v(" "),t("li",[t("p",[e._v("将自己作为"),t("code",[e._v("@author")]),e._v("添加到要进行实质性修改的.java 文件中(不仅仅是外观上的更改)。")])]),e._v(" "),t("li",[t("p",[e._v("添加一些 Javadocs,如果你更改了名称空间,还可以添加一些 XSDDOC 元素。")])]),e._v(" "),t("li",[t("p",[e._v("几个单元测试也会有很大帮助——必须有人去做。")])]),e._v(" "),t("li",[t("p",[e._v("如果没有其他人正在使用你的分支,请将它重新设置为当前的主分支(或主项目中的其他目标分支)。")])]),e._v(" "),t("li",[t("p",[e._v("在写提交消息时,请遵循"),t("a",{attrs:{href:"https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("这些约定"),t("OutboundLink")],1),e._v(",如果你正在修复现有的问题,请在提交消息的末尾添加"),t("code",[e._v("Fixes gh-XXXX")]),e._v("(其中 xxxx 是问题编号)。")])])]),e._v(" "),t("h3",{attrs:{id:"_3-4-checkstyle"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-checkstyle"}},[e._v("#")]),e._v(" 3.4.checkstyle")]),e._v(" "),t("p",[e._v("Spring Cloud构建附带一组 CheckStyle 规则。你可以在"),t("code",[e._v("spring-cloud-build-tools")]),e._v("模块中找到它们。该模块下最值得注意的文件是:")]),e._v(" "),t("p",[e._v("Spring-云构建工具/")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("└── src\n    ├── checkstyle\n    │   └── checkstyle-suppressions.xml (3)\n    └── main\n        └── resources\n            ├── checkstyle-header.txt (2)\n            └── checkstyle.xml (1)\n")])])]),t("table",[t("thead",[t("tr",[t("th",[t("strong",[e._v("1")])]),e._v(" "),t("th",[e._v("默认的 checkstyle 规则")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[t("strong",[e._v("2")])]),e._v(" "),t("td",[e._v("文件头设置")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("3")])]),e._v(" "),t("td",[e._v("默认抑制规则")])])])]),e._v(" "),t("h4",{attrs:{id:"_3-4-1-checkstyle-配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-1-checkstyle-配置"}},[e._v("#")]),e._v(" 3.4.1.checkstyle 配置")]),e._v(" "),t("p",[e._v("checkstyle 规则是"),t("strong",[e._v("默认禁用")]),e._v("。要将 checkstyle 添加到项目中,只需定义以下属性和插件。")]),e._v(" "),t("p",[e._v("POM.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<properties>\n<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> (1)\n        <maven-checkstyle-plugin.failsOnViolation>true\n        </maven-checkstyle-plugin.failsOnViolation> (2)\n        <maven-checkstyle-plugin.includeTestSourceDirectory>true\n        </maven-checkstyle-plugin.includeTestSourceDirectory> (3)\n</properties>\n\n<build>\n        <plugins>\n            <plugin> (4)\n                <groupId>io.spring.javaformat</groupId>\n                <artifactId>spring-javaformat-maven-plugin</artifactId>\n            </plugin>\n            <plugin> (5)\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n        </plugins>\n\n    <reporting>\n        <plugins>\n            <plugin> (5)\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </reporting>\n</build>\n")])])]),t("table",[t("thead",[t("tr",[t("th",[t("strong",[e._v("1")])]),e._v(" "),t("th",[e._v("构建 checkstyle 错误失败")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[t("strong",[e._v("2")])]),e._v(" "),t("td",[e._v("构建 checkstyle 冲突失败")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("3")])]),e._v(" "),t("td",[e._v("CheckStyle 还分析了测试源")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("4")])]),e._v(" "),t("td",[e._v("添加 Spring Java 格式插件,该插件将重新格式化你的代码,以传递大多数 CheckStyle 格式设置规则")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("5")])]),e._v(" "),t("td",[e._v("将 CheckStyle 插件添加到构建和报告阶段")])])])]),e._v(" "),t("p",[e._v("如果你需要抑制一些规则(例如行长需要更长),那么在"),t("code",[e._v("${project.root}/src/checkstyle/checkstyle-suppressions.xml")]),e._v("下定义一个文件就足够了。示例:")]),e._v(" "),t("p",[e._v("projectRoot/SRC/checkstyle/checkstyle-suppresions.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('<?xml version="1.0"?>\n<!DOCTYPE suppressions PUBLIC\n        "-//Puppy Crawl//DTD Suppressions 1.1//EN"\n        "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">\n<suppressions>\n    <suppress files=".*ConfigServerApplication\\.java" checks="HideUtilityClassConstructor"/>\n    <suppress files=".*ConfigClientWatch\\.java" checks="LineLengthCheck"/>\n</suppressions>\n')])])]),t("p",[e._v("建议将"),t("code",[e._v("${spring-cloud-build.rootFolder}/.editorconfig")]),e._v(""),t("code",[e._v("${spring-cloud-build.rootFolder}/.springformat")]),e._v("复制到你的项目中。这样,将应用一些默认的格式设置规则。你可以通过运行以下脚本来实现此目的:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig\n$ touch .springformat\n")])])]),t("h3",{attrs:{id:"_3-5-ide-设置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-ide-设置"}},[e._v("#")]),e._v(" 3.5.IDE 设置")]),e._v(" "),t("h4",{attrs:{id:"_3-5-1-intellij-思想"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-1-intellij-思想"}},[e._v("#")]),e._v(" 3.5.1.Intellij 思想")]),e._v(" "),t("p",[e._v("为了设置 IntelliJ,你应该导入我们的编码约定、检查配置文件并设置 CheckStyle 插件。以下文件可以在"),t("a",{attrs:{href:"https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Build"),t("OutboundLink")],1),e._v("项目中找到。")]),e._v(" "),t("p",[e._v("Spring-云构建工具/")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("└── src\n    ├── checkstyle\n    │   └── checkstyle-suppressions.xml (3)\n    └── main\n        └── resources\n            ├── checkstyle-header.txt (2)\n            ├── checkstyle.xml (1)\n            └── intellij\n                ├── Intellij_Project_Defaults.xml (4)\n                └── Intellij_Spring_Boot_Java_Conventions.xml (5)\n")])])]),t("table",[t("thead",[t("tr",[t("th",[t("strong",[e._v("1")])]),e._v(" "),t("th",[e._v("默认的 checkstyle 规则")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[t("strong",[e._v("2")])]),e._v(" "),t("td",[e._v("文件头设置")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("3")])]),e._v(" "),t("td",[e._v("默认抑制规则")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("4")])]),e._v(" "),t("td",[e._v("适用大多数 CheckStyle 规则的 IntelliJ 的项目默认值")])]),e._v(" "),t("tr",[t("td",[t("strong",[e._v("5")])]),e._v(" "),t("td",[e._v("适用大多数 CheckStyle 规则的 IntelliJ 的项目风格约定")])])])]),e._v(" "),t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/images/intellij-code-style.png",alt:"Code style"}})]),e._v(" "),t("p",[e._v("图 1。代码样式")]),e._v(" "),t("p",[e._v("转到"),t("code",[e._v("File``Settings``Editor``Code style")]),e._v("。点击"),t("code",[e._v("Scheme")]),e._v("区域旁边的图标。在这里,单击"),t("code",[e._v("Import Scheme")]),e._v("值并选择"),t("code",[e._v("Intellij IDEA code style XML")]),e._v("选项。导入"),t("code",[e._v("spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml")]),e._v("文件。")]),e._v(" "),t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/images/intellij-inspections.png",alt:"Code style"}})]),e._v(" "),t("p",[e._v("图 2。检查剖面")]),e._v(" "),t("p",[e._v("转到"),t("code",[e._v("File``Settings``Editor``Inspections")]),e._v("。点击"),t("code",[e._v("Profile")]),e._v("区域旁边的图标。在那里,单击"),t("code",[e._v("Import Profile")]),e._v("并导入"),t("code",[e._v("spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml")]),e._v("文件。")]),e._v(" "),t("p",[e._v("checkstyle")]),e._v(" "),t("p",[e._v("要让 IntelliJ 使用 CheckStyle,你必须安装"),t("code",[e._v("Checkstyle")]),e._v("插件。建议还安装"),t("code",[e._v("Assertions2Assertj")]),e._v("来自动转换 JUnit 断言")]),e._v(" "),t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/images/intellij-checkstyle.png",alt:"Checkstyle"}})]),e._v(" "),t("p",[e._v("转到"),t("code",[e._v("File``Settings``Other settings``Checkstyle")]),e._v("。点击"),t("code",[e._v("Configuration file")]),e._v("区域中的"),t("code",[e._v("+")]),e._v("图标。在这里,你必须定义应该从哪里选择 CheckStyle 规则。在上面的图片中,我们从克隆的云构建存储库中选择了规则。但是,你可以指向 Spring Cloud Build 的 GitHub 存储库(例如"),t("code",[e._v("checkstyle.xml")]),e._v(":"),t("code",[e._v("[raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml)")]),e._v(")。我们需要提供以下变量:")]),e._v(" "),t("ul",[t("li",[t("p",[t("code",[e._v("checkstyle.header.file")]),e._v("-请将其指向 Spring Cloud Build 的"),t("code",[e._v("spring-cloud-build-tools/src/main/resources/checkstyle-header.txt")]),e._v("文件,可以在你的克隆 repo 中,也可以通过"),t("code",[e._v("[raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt)")]),e._v("URL。")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("checkstyle.suppressions.file")]),e._v("-默认抑制。请将它指向 Spring Cloud Build 的"),t("code",[e._v("spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml")]),e._v("文件,或者在你的克隆 repo 中,或者通过"),t("code",[e._v("[raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml)")]),e._v("URL。")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("checkstyle.additional.suppressions.file")]),e._v("-此变量对应于本地项目中的抑制。例如,你正在处理"),t("code",[e._v("spring-cloud-contract")]),e._v("。然后指向"),t("code",[e._v("project-root/src/checkstyle/checkstyle-suppressions.xml")]),e._v("文件夹。"),t("code",[e._v("spring-cloud-contract")]),e._v("的示例是:"),t("code",[e._v("/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml")]),e._v("")])])]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("请记住将"),t("code",[e._v("Scan Scope")]),e._v("设置为"),t("code",[e._v("All sources")]),e._v(",因为我们为生产和测试源应用了 checkstyle 规则。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h3",{attrs:{id:"_3-6-重复查找器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-重复查找器"}},[e._v("#")]),e._v(" 3.6.重复查找器")]),e._v(" "),t("p",[e._v("Spring Cloud构建带来了"),t("code",[e._v("basepom:duplicate-finder-maven-plugin")]),e._v(",这使得能够在 Java Classpath 上标记重复的和冲突的类和资源。")]),e._v(" "),t("h4",{attrs:{id:"_3-6-1-重复查找器配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-1-重复查找器配置"}},[e._v("#")]),e._v(" 3.6.1.重复查找器配置")]),e._v(" "),t("p",[e._v("重复查找器是"),t("strong",[e._v("默认启用")]),e._v(",将在 Maven 构建的"),t("code",[e._v("verify")]),e._v("阶段运行,但是只有在将"),t("code",[e._v("duplicate-finder-maven-plugin")]),e._v("添加到项目的"),t("code",[e._v("build")]),e._v("部分"),t("code",[e._v("POM.xml")]),e._v("时,它才会在项目中生效。")]),e._v(" "),t("p",[e._v("pom.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<build>\n    <plugins>\n        <plugin>\n            <groupId>org.basepom.maven</groupId>\n            <artifactId>duplicate-finder-maven-plugin</artifactId>\n        </plugin>\n    </plugins>\n</build>\n")])])]),t("p",[e._v("对于其他属性,我们设置了"),t("a",{attrs:{href:"https://github.com/basepom/duplicate-finder-maven-plugin/wiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("插件文档"),t("OutboundLink")],1),e._v("中列出的默认值。")]),e._v(" "),t("p",[e._v("你可以轻松地重写它们,但可以使用"),t("code",[e._v("duplicate-finder-maven-plugin")]),e._v("前缀设置所选属性的值。例如,将"),t("code",[e._v("duplicate-finder-maven-plugin.skip")]),e._v("设置为"),t("code",[e._v("true")]),e._v(",以便在构建中跳过重复检查。")]),e._v(" "),t("p",[e._v("如果需要将"),t("code",[e._v("ignoredClassPatterns")]),e._v(""),t("code",[e._v("ignoredResourcePatterns")]),e._v("添加到设置中,请确保将它们添加到项目的插件配置部分中:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<build>\n    <plugins>\n        <plugin>\n            <groupId>org.basepom.maven</groupId>\n            <artifactId>duplicate-finder-maven-plugin</artifactId>\n            <configuration>\n                <ignoredClassPatterns>\n                    <ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>\n                    <ignoredClassPattern>.*module-info</ignoredClassPattern>\n                </ignoredClassPatterns>\n                <ignoredResourcePatterns>\n                    <ignoredResourcePattern>changelog.txt</ignoredResourcePattern>\n                </ignoredResourcePatterns>\n            </configuration>\n        </plugin>\n    </plugins>\n</build>\n")])])])])}),[],!1,null,null,null);r.default=i.exports}}]);