├── spring-webflux-reactive ├── .gitignore ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── spring │ │ │ │ └── webflux │ │ │ │ ├── reactive │ │ │ │ ├── repository │ │ │ │ │ ├── HighwayTraffic.java │ │ │ │ │ └── HighwayTrafficSimulator.java │ │ │ │ ├── HighwayRouter.java │ │ │ │ ├── HighwayHandler.java │ │ │ │ ├── model │ │ │ │ │ └── Vehicle.java │ │ │ │ └── client │ │ │ │ │ └── HighwayWebClient.java │ │ │ │ └── HighwayApplication.java │ │ └── resources │ │ │ ├── application.yml │ │ │ ├── banner.txt │ │ │ └── logback.xml │ └── test │ │ └── java │ │ └── com │ │ └── spring │ │ └── webflux │ │ └── HighwayApplicationTest.java ├── target │ └── classes │ │ └── META-INF │ │ ├── maven │ │ └── com.spring.webflux.reactive │ │ │ └── spring-webflux-reactive │ │ │ ├── pom.properties │ │ │ └── pom.xml │ │ └── MANIFEST.MF ├── .project ├── .classpath └── pom.xml ├── .gitignore └── README.md /spring-webflux-reactive/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /spring-webflux-reactive/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /spring-webflux-reactive/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /spring-webflux-reactive/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.8 6 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/repository/HighwayTraffic.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive.repository; 2 | 3 | import com.spring.webflux.reactive.model.Vehicle; 4 | 5 | import reactor.core.publisher.Flux; 6 | 7 | public interface HighwayTraffic { 8 | 9 | public Flux flowTraffic(); 10 | 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | root: INFO 4 | org.springframework.web: INFO 5 | com.netflix: INFO 6 | org.springframework.security: INFO 7 | org.springframework.cloud: INFO 8 | org.springframework.boot: INFO 9 | io.netty: ERROR 10 | reactor.ipc: ERROR 11 | reactor: ERROR 12 | com.spring.webflux: ERROR 13 | org.springframework.web.reactive: ERROR -------------------------------------------------------------------------------- /spring-webflux-reactive/target/classes/META-INF/maven/com.spring.webflux.reactive/spring-webflux-reactive/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Sat Apr 14 12:53:02 CEST 2018 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.spring.webflux.reactive 5 | m2e.projectName=spring-webflux-reactive 6 | m2e.projectLocation=C\:\\Users\\Ualter\\Developer\\spring-reactive-webflux\\spring-webflux-reactive 7 | artifactId=spring-webflux-reactive 8 | -------------------------------------------------------------------------------- /spring-webflux-reactive/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Implementation-Title: spring-webflux-reactive 3 | Implementation-Version: 0.0.1-SNAPSHOT 4 | Built-By: Ualter 5 | Implementation-Vendor-Id: com.spring.webflux.reactive 6 | Build-Jdk: 1.8.0_144 7 | Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo 8 | ot-starter-parent/spring-webflux-reactive 9 | Created-By: Maven Integration for Eclipse 10 | 11 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/HighwayApplication.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.reactive.config.EnableWebFlux; 6 | 7 | @SpringBootApplication 8 | @EnableWebFlux 9 | public class HighwayApplication 10 | { 11 | public static void main( String[] args ) 12 | { 13 | SpringApplication.run(HighwayApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spring-webflux-reactive/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-webflux-reactive 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-reactive-webflux 2 | 3 | ## Run it with... 4 | ``` 5 | mvn test 6 | 7 | ******************************************************************************** 8 | __ ___ __ _____ 9 | / / / (_)___ _/ /_ _ ______ ___ __ / ___/___ ______ _____ _____ 10 | / /_/ / / __ `/ __ \ | /| / / __ `/ / / / \__ \/ _ \/ ___/ | / / _ \/ ___/ 11 | / __ / / /_/ / / / / |/ |/ / /_/ / /_/ / ___/ / __/ / | |/ / __/ / 12 | /_/ /_/_/\__, /_/ /_/|__/|__/\__,_/\__, / /____/\___/_/ |___/\___/_/ 13 | /____/ /____/ 14 | 15 | ******************************************************************************** 16 | 17 | ``` 18 | 19 | https://ualterazambuja.com/2018/04/22/reactive-programming-with-spring-webflux/ 20 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ******************************************************************************** 3 | ${AnsiColor.BRIGHT_YELLOW} __ ___ __ _____ 4 | ${AnsiColor.BRIGHT_YELLOW} / / / (_)___ _/ /_ _ ______ ___ __ / ___/___ ______ _____ _____ 5 | ${AnsiColor.BRIGHT_YELLOW} / /_/ / / __ `/ __ \ | /| / / __ `/ / / / \__ \/ _ \/ ___/ | / / _ \/ ___/ 6 | ${AnsiColor.BRIGHT_YELLOW} / __ / / /_/ / / / / |/ |/ / /_/ / /_/ / ___/ / __/ / | |/ / __/ / 7 | ${AnsiColor.BRIGHT_YELLOW} /_/ /_/_/\__, /_/ /_/|__/|__/\__,_/\__, / /____/\___/_/ |___/\___/_/ 8 | ${AnsiColor.BRIGHT_YELLOW} /____/ /____/ 9 | ${AnsiColor.BRIGHT_YELLOW} 10 | ******************************************************************************** 11 | 12 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/HighwayRouter.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.reactive.function.server.RequestPredicates; 7 | import org.springframework.web.reactive.function.server.RouterFunction; 8 | import org.springframework.web.reactive.function.server.RouterFunctions; 9 | import org.springframework.web.reactive.function.server.ServerResponse; 10 | 11 | @Component 12 | public class HighwayRouter { 13 | 14 | @Bean 15 | public RouterFunction route(HighwayHandler highwayHandler) { 16 | return RouterFunctions 17 | .route(RequestPredicates.GET("/vehicles") 18 | .and(RequestPredicates.accept(MediaType.APPLICATION_STREAM_JSON)), 19 | highwayHandler::vehicleDetected); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/HighwayHandler.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.MediaType; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.reactive.function.server.ServerRequest; 7 | import org.springframework.web.reactive.function.server.ServerResponse; 8 | 9 | import com.spring.webflux.reactive.model.Vehicle; 10 | import com.spring.webflux.reactive.repository.HighwayTraffic; 11 | 12 | import reactor.core.publisher.Mono; 13 | 14 | @Component 15 | public class HighwayHandler { 16 | 17 | @Autowired 18 | HighwayTraffic highwayTraffic; 19 | 20 | public Mono vehicleDetected(ServerRequest request) { 21 | return ServerResponse.ok() 22 | .contentType(MediaType.APPLICATION_STREAM_JSON) 23 | .body(highwayTraffic.flowTraffic(),Vehicle.class); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /spring-webflux-reactive/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/test/java/com/spring/webflux/HighwayApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.spring.webflux.reactive.client.HighwayWebClient; 10 | 11 | import reactor.core.Disposable; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest(properties = "spring.main.web-application-type=reactive", webEnvironment = WebEnvironment.DEFINED_PORT) 15 | public class HighwayApplicationTest { 16 | 17 | 18 | @Test 19 | public void testVehiclesFlowingAll() 20 | { 21 | HighwayWebClient vehiclesWebClient = new HighwayWebClient(); 22 | Disposable disposable = vehiclesWebClient.vehicleDetected(); 23 | try { 24 | Thread.sleep(32000); 25 | } catch (InterruptedException e) { 26 | e.printStackTrace(); 27 | } finally { 28 | disposable.dispose(); 29 | } 30 | } 31 | 32 | @Test 33 | public void testVehiclesFlowing120KmHigher() 34 | { 35 | HighwayWebClient vehiclesWebClient = new HighwayWebClient(); 36 | Disposable disposable = vehiclesWebClient.vehicleHigherThen120Detected(); 37 | try { 38 | Thread.sleep(32000); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } finally { 42 | disposable.dispose(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/model/Vehicle.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Vehicle implements Serializable { 6 | 7 | private static final long serialVersionUID = -6415713305955411683L; 8 | private String carPlateNumber; 9 | private Long weight; 10 | private Integer speed; 11 | private String color; 12 | private Integer modelYear; 13 | private String gasType; 14 | 15 | public Vehicle() { 16 | 17 | } 18 | public Vehicle(String carPlateNumber, Long weight, Integer speed, String color, Integer modelYear, String gasType) { 19 | super(); 20 | this.carPlateNumber = carPlateNumber; 21 | this.weight = weight; 22 | this.speed = speed; 23 | this.color = color; 24 | this.modelYear = modelYear; 25 | this.gasType = gasType; 26 | } 27 | public String getCarPlateNumber() { 28 | return carPlateNumber; 29 | } 30 | public void setCarPlateNumber(String carPlateNumber) { 31 | this.carPlateNumber = carPlateNumber; 32 | } 33 | public Long getWeight() { 34 | return weight; 35 | } 36 | public void setWeight(Long weight) { 37 | this.weight = weight; 38 | } 39 | public Integer getSpeed() { 40 | return speed; 41 | } 42 | public void setSpeed(Integer speed) { 43 | this.speed = speed; 44 | } 45 | public String getColor() { 46 | return color; 47 | } 48 | public void setColor(String color) { 49 | this.color = color; 50 | } 51 | public Integer getModelYear() { 52 | return modelYear; 53 | } 54 | public void setModelYear(Integer modelYear) { 55 | this.modelYear = modelYear; 56 | } 57 | public String getGasType() { 58 | return gasType; 59 | } 60 | public void setGasType(String gasType) { 61 | this.gasType = gasType; 62 | } 63 | @Override 64 | public String toString() { 65 | return String.format("Vehicle [carPlateNumber=%s, weight=%s, speed=%s, color=%s, modelYear=%s, gasType=%s]", 66 | carPlateNumber, weight, speed, color, modelYear, gasType); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/repository/HighwayTrafficSimulator.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive.repository; 2 | 3 | import java.text.DecimalFormat; 4 | import java.time.LocalDateTime; 5 | import java.time.temporal.ChronoUnit; 6 | import java.util.concurrent.ThreadLocalRandom; 7 | 8 | import org.apache.commons.text.RandomStringGenerator; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.stereotype.Service; 12 | 13 | import com.spring.webflux.reactive.model.Vehicle; 14 | 15 | import reactor.core.publisher.Flux; 16 | 17 | @Service 18 | public class HighwayTrafficSimulator implements HighwayTraffic { 19 | 20 | private static Logger LOGGER = LoggerFactory.getLogger(HighwayTrafficSimulator.class); 21 | private static DecimalFormat plateFormatNumber = new DecimalFormat("0000"); 22 | 23 | public HighwayTrafficSimulator() { 24 | } 25 | 26 | public Flux flowTraffic() { 27 | LocalDateTime startTime = LocalDateTime.now(); 28 | 29 | return Flux.create(fluxSink -> { 30 | boolean inFrameTime = true; 31 | int index = 1; 32 | while (index <= 30000 && inFrameTime && !fluxSink.isCancelled() ) { 33 | fluxSink.next(HighwayUtilities.simulateTraffic()); 34 | index++; 35 | 36 | long timeMinutesHighwayOpened = startTime.until(LocalDateTime.now(), 37 | ChronoUnit.MILLIS); 38 | if (timeMinutesHighwayOpened > 30000) { 39 | LOGGER.info("TrafficSimulator finish --> With timer"); 40 | inFrameTime = false; 41 | } 42 | } 43 | }).share(); 44 | } 45 | 46 | private static String[] COLORS = { "Blue", "White", "Silver", "Black", "Metalic Green", "Orange", "Yellow" }; 47 | private static String[] GAS_TYPE = { "Diesel", "Gasoline", "Gas", "Eletric", "Alcohol" }; 48 | 49 | private static class HighwayUtilities { 50 | 51 | private static Vehicle simulateTraffic() { 52 | RandomStringGenerator rndStringGen = new RandomStringGenerator.Builder().withinRange('A', 'Z').build(); 53 | 54 | StringBuffer sb = new StringBuffer(rndStringGen.generate(3).toUpperCase()); 55 | sb.append(" "); 56 | sb.append(plateFormatNumber.format(ThreadLocalRandom.current().nextInt(0, 9999))); 57 | String carPlateNumber = sb.toString(); 58 | 59 | Long weight = ThreadLocalRandom.current().nextLong(250L, 4500L); 60 | Integer speed = ThreadLocalRandom.current().nextInt(60, 175); 61 | 62 | String color = COLORS[ThreadLocalRandom.current().nextInt(0, 6)]; 63 | Integer modelYear = ThreadLocalRandom.current().nextInt(1975, 2018); 64 | String gasType = GAS_TYPE[ThreadLocalRandom.current().nextInt(0, 4)]; 65 | 66 | return new Vehicle(carPlateNumber, weight, speed, color, modelYear, gasType); 67 | } 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /spring-webflux-reactive/src/main/java/com/spring/webflux/reactive/client/HighwayWebClient.java: -------------------------------------------------------------------------------- 1 | package com.spring.webflux.reactive.client; 2 | 3 | import java.time.Duration; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.reactive.function.client.WebClient; 8 | 9 | import com.spring.webflux.reactive.model.Vehicle; 10 | 11 | import reactor.core.Disposable; 12 | import reactor.core.scheduler.Schedulers; 13 | 14 | public class HighwayWebClient { 15 | 16 | private WebClient webClient = WebClient.builder() 17 | .baseUrl("http://localhost:8080") 18 | .build(); 19 | 20 | public Disposable vehicleDetected() { 21 | AtomicInteger counter = new AtomicInteger(0); 22 | return webClient.get() 23 | .uri("/vehicles") 24 | .accept(MediaType.APPLICATION_STREAM_JSON) 25 | .exchange() 26 | .publishOn(Schedulers.single()) 27 | .flatMapMany(response -> response.bodyToFlux(Vehicle.class)) 28 | .delayElements(Duration.ofMillis(1000)) 29 | .subscribe(s -> { 30 | System.out.println(counter.incrementAndGet() + " >>>>>>>>>>>> " + s); 31 | }, 32 | err -> System.out.println("Error on Vehicle Stream: " + err), 33 | () -> System.out.println("Vehicle stream stoped!")); 34 | } 35 | 36 | public Disposable vehicleHigherThen120Detected() { 37 | AtomicInteger counter = new AtomicInteger(0); 38 | return webClient.get() 39 | .uri("/vehicles") 40 | .accept(MediaType.APPLICATION_STREAM_JSON) 41 | .exchange() 42 | .flatMapMany(response -> response.bodyToFlux(Vehicle.class)) 43 | .filter(v -> v.getSpeed() > 120) 44 | .delayElements(Duration.ofMillis(250)) 45 | .subscribe(s -> { 46 | System.out.println(counter.incrementAndGet() + " >> 120Km+ >> " + s); 47 | }, 48 | err -> System.out.println("Error on Vehicle Stream: " + err), 49 | () -> System.out.println("Vehicle stream stoped!")); 50 | } 51 | 52 | /** 53 | * Used for development reasons only 54 | * To run the sample, can be done by: mvn test (SpringBootTest) 55 | */ 56 | public static void main(String[] args) { 57 | HighwayWebClient vehiclesWebClient = new HighwayWebClient(); 58 | Disposable disposable = vehiclesWebClient.vehicleDetected(); 59 | try { 60 | Thread.sleep(32000); 61 | } catch (InterruptedException e) { 62 | e.printStackTrace(); 63 | } finally { 64 | disposable.dispose(); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /spring-webflux-reactive/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.spring.webflux.reactive 7 | spring-webflux-reactive 8 | 0.0.1-SNAPSHOT 9 | jar 10 | spring-webflux-reactive 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 2.0.1.RELEASE 16 | 17 | 18 | 19 | 20 | UTF-8 21 | 1.8 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-webflux 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | io.projectreactor 38 | reactor-test 39 | test 40 | 41 | 42 | 43 | org.apache.commons 44 | commons-lang3 45 | 46 | 47 | 48 | org.apache.commons 49 | commons-text 50 | 1.3 51 | 52 | 53 | 54 | io.netty 55 | netty-transport-native-epoll 56 | 4.0.27.Final 57 | linux-x86_64 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-test 63 | test 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-devtools 69 | 70 | 71 | 72 | 73 | 85 | 86 | -------------------------------------------------------------------------------- /spring-webflux-reactive/target/classes/META-INF/maven/com.spring.webflux.reactive/spring-webflux-reactive/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.spring.webflux.reactive 7 | spring-webflux-reactive 8 | 0.0.1-SNAPSHOT 9 | jar 10 | spring-webflux-reactive 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 2.0.1.RELEASE 16 | 17 | 18 | 19 | 20 | UTF-8 21 | 1.8 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-webflux 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | io.projectreactor 38 | reactor-test 39 | test 40 | 41 | 42 | 43 | org.apache.commons 44 | commons-lang3 45 | 46 | 47 | 48 | org.apache.commons 49 | commons-text 50 | 1.3 51 | 52 | 53 | 54 | io.netty 55 | netty-transport-native-epoll 56 | 4.0.27.Final 57 | linux-x86_64 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-test 63 | test 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-devtools 69 | 70 | 71 | 72 | 73 | 85 | 86 | --------------------------------------------------------------------------------