programming:spring
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
programming:spring [2023/11/01 07:31] – removed - external edit (Unknown date) 127.0.0.1 | programming:spring [2024/07/14 19:36] (current) – [Docker] skipidar | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== Spring Boot ====== | ||
+ | Spring boot - is a Java framework, which claims to retrieve the default configurations from the libraries loaded to the path. | ||
+ | |||
+ | ==== Rest Controller ==== | ||
+ | Logging the exposed endpoints. | ||
+ | To log the exposed endpoints the change in the application.properties is required: | ||
+ | |||
+ | application.properties | ||
+ | < | ||
+ | logging.level.web=TRACE | ||
+ | logging.level.org.springframework.web=TRACE | ||
+ | </ | ||
+ | |||
+ | |||
+ | Example output | ||
+ | < | ||
+ | 12: | ||
+ | i.d.l.d.g.RestGroupController: | ||
+ | {GET [/rest/, / | ||
+ | {POST / | ||
+ | {POST / | ||
+ | {DELETE / | ||
+ | {GET [/rest/, / | ||
+ | {GET [/rest/, / | ||
+ | {DELETE / | ||
+ | 12: | ||
+ | i.d.l.d.r.RestRoleController: | ||
+ | {GET [/rest/, / | ||
+ | {POST / | ||
+ | {DELETE / | ||
+ | {POST / | ||
+ | {DELETE / | ||
+ | </ | ||
+ | |||
+ | ===== New project ===== | ||
+ | Use [[https:// | ||
+ | |||
+ | Import it to the Idea IDE via: | ||
+ | {{https:// | ||
+ | |||
+ | |||
+ | ===== Gradle ===== | ||
+ | |||
+ | Spring boot is normally either | ||
+ | * packaged to an executable jar, together with dependencies, | ||
+ | * packaged as a deployable war, so that it may be deployed to a Tomcat etc. | ||
+ | |||
+ | == Running the app == | ||
+ | |||
+ | Running the app with gradle, choosing the port | ||
+ | < | ||
+ | ./gradlew bootRun --args=' | ||
+ | </ | ||
+ | |||
+ | |||
+ | == Building a JAR == | ||
+ | |||
+ | To create a Jar with gradle - add the following to build.gradle | ||
+ | |||
+ | to automagically resolve dependencies within the current spring boot version - you must apply a special plugin. \\ | ||
+ | The dependencies will be resolved acording to the BOM - bill of materials. \\ | ||
+ | Check https:// | ||
+ | < | ||
+ | apply plugin: ' | ||
+ | </ | ||
+ | |||
+ | Build the jar by using **gradlew**. \\ This will produce a JAR e.g. under **build\libs\PROJECTNAME\complete.jar** | ||
+ | < | ||
+ | ../ | ||
+ | </ | ||
+ | |||
+ | Start the jar | ||
+ | < | ||
+ | java -jar complete.jar | ||
+ | </ | ||
+ | |||
+ | {{https:// | ||
+ | |||
+ | == Building a WAR == | ||
+ | |||
+ | build.gradle | ||
+ | < | ||
+ | apply plugin: ' | ||
+ | apply plugin: ' | ||
+ | </ | ||
+ | |||
+ | Build the jar by using **gradlew**. \\ This will produce a JAR e.g. under **build\libs\PROJECTNAME\complete.war** | ||
+ | < | ||
+ | ../ | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Spring Profiles ====== | ||
+ | |||
+ | Spring profiles can be activated in multiple ways, e.g. | ||
+ | |||
+ | by setting the environment variable | ||
+ | |||
+ | < | ||
+ | export spring_profiles_active=dev | ||
+ | </ | ||
+ | |||
+ | |||
+ | by passing an argument to the java virtual machine | ||
+ | < | ||
+ | -Dspring.profiles.active=dev | ||
+ | </ | ||
+ | |||
+ | |||
+ | When activated - you get the option to create a profile dependant properties files. | ||
+ | |||
+ | |||
+ | * .properties files are located in / | ||
+ | * ./ | ||
+ | * ./ | ||
+ | * ./ | ||
+ | * ./ | ||
+ | * .properties files are additive | ||
+ | |||
+ | |||
+ | To pick a default profile - you need to set in in applicaiton.properties | ||
+ | |||
+ | application.properties | ||
+ | <sxh shell> | ||
+ | # the default profile which is used. Can be overridden by specifying the Spring profile as -Dspring.profiles.active or in another way. | ||
+ | # without that the " | ||
+ | spring.profiles.active=dev | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Continous build ==== | ||
+ | Spring boot applications - can be configured to | ||
+ | - react on file changes | ||
+ | - rebuild the application e.g. to a jar | ||
+ | - redeploy the jar, e.g. to the ThomCat | ||
+ | |||
+ | |||
+ | |||
+ | == Step 1 == | ||
+ | |||
+ | Add dev-tools to the dependencies, | ||
+ | so that the rebuilt app is hot-swaped on the app server. | ||
+ | |||
+ | In **build.gradle** | ||
+ | < | ||
+ | dependencies { | ||
+ | |||
+ | // makes Spring boot hot swap rebuilt jar to tomcat | ||
+ | developmentOnly ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | == Step 2 == | ||
+ | |||
+ | In a separate terminal, start the continuous build of application. | ||
+ | |||
+ | Do that in a separate terminal, because the command doesn' | ||
+ | |||
+ | It works in **Vagrant**, | ||
+ | But unfortunately, | ||
+ | To trigger rebuild, hot-swap - one needs to change some file in the **vagrant-guest-machine**. | ||
+ | |||
+ | Starts continuos build skipping the tests | ||
+ | < | ||
+ | ./gradlew build -xtest --continuous | ||
+ | </ | ||
+ | |||
+ | To propagate a change triggering a rebuild - you need to modify the file on the guest-system | ||
+ | < | ||
+ | echo "" | ||
+ | </ | ||
+ | |||
+ | == Step3 Launch the app == | ||
+ | |||
+ | The app will be built and propagated | ||
+ | < | ||
+ | ./gradlew bootRun --args=' | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ====== Native Image ====== | ||
+ | |||
+ | # Prerequisites | ||
+ | |||
+ | Install java | ||
+ | |||
+ | < | ||
+ | # java open GraalVM from liberica " | ||
+ | sdk install java 22.3.r17-nik < /dev/null | ||
+ | |||
+ | # switch | ||
+ | sdk use java 22.3.r17-nik | ||
+ | |||
+ | # set the Java_home | ||
+ | source " | ||
+ | </ | ||
+ | |||
+ | # Quickstart | ||
+ | |||
+ | Build a native image | ||
+ | |||
+ | < | ||
+ | ./gradlew nativeCompile | ||
+ | </ | ||
+ | |||
+ | [native-image-plugin] Native Image written to: / | ||
+ | |||
+ | Run | ||
+ | |||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== Rest Controller ==== | ||
+ | |||
+ | CRUD repositories '' | ||
+ | |||
+ | can create queries by convention. | ||
+ | |||
+ | Just name the methods according to the convention https:// | ||
+ | and they will be mapped to queries. | ||
+ | |||
+ | |||
+ | ===== API Versioning ==== | ||
+ | |||
+ | URI Versioning - Twitter | ||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | Request Parameter versioning - Amazon | ||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | (Custom) headers versioning - Microsoft | ||
+ | * SAME-URL headers=(X-API-VERSION=l] | ||
+ | * SAME-URL headers=[X-API-VERSION=2] | ||
+ | |||
+ | |||
+ | Media type versioning - GitHub | ||
+ | * SAME-URL produces=application/ | ||
+ | * SAME-URL produces=application/ | ||
+ | |||
+ | |||
+ | ===== Libs ===== | ||
+ | |||
+ | ==== Hystrix - Circuit Breaker ==== | ||
+ | https:// | ||
+ | |||
+ | ==== Feign - declarative REST client ==== | ||
+ | |||
+ | Reduces the glue-code to the minimum. | ||
+ | Need only to express - what to call and receive the response DTO | ||
+ | |||
+ | https:// | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <sxh java> | ||
+ | package com.in28minutes.microservices.currencyconversionservice; | ||
+ | |||
+ | import org.springframework.cloud.netflix.feign.FeignClient; | ||
+ | import org.springframework.web.bind.annotation.GetMapping; | ||
+ | import org.springframework.web.bind.annotation.PathVariable; | ||
+ | |||
+ | @FeignClient(name = " | ||
+ | public interface CurrencyExchangeServiceProxy { | ||
+ | |||
+ | @GetMapping("/ | ||
+ | public CurrencyConversionBean retrieveExchangeValue | ||
+ | (@PathVariable(" | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | ==== Ribbon - Client based load balancer ==== | ||
+ | |||
+ | Exposes multiple deployments under one URL | ||
+ | |||
+ | {{https:// | ||
+ | |||
+ | {{https:// | ||
+ | |||
+ | |||
+ | ==== Zuul API Gateway ==== | ||
+ | |||
+ | API Gateway in SPring | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== EUreka Namingserver ==== | ||
+ | |||
+ | Allows to register / discover services on a naming server. | ||
+ | |||
+ | Has a GUI to list available services. | ||
+ | |||
+ | {{https:// | ||
+ | |||
+ | |||
+ | |||
+ | ==== Cloud Sleuth - unique tracing id to requests ==== | ||
+ | |||
+ | adds a unique tracing id to requests | ||
+ | |||
+ | |||
+ | |||
+ | ==== Zipkin - Distributed Tracing Server ==== | ||
+ | |||
+ | |||
+ | Central tracing server. | ||
+ | |||
+ | * Like ELK. | ||
+ | * and CloudWatch | ||
+ | |||
+ | |||
+ | {{https:// | ||
+ | {{https:// | ||
+ | ==== Spring Cloud Bus ==== | ||
+ | |||
+ | Can use it to refresh the configs of all services, | ||
+ | by sending a message via the bus. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Docker ===== | ||
+ | |||
+ | == Build manually without gradle == | ||
+ | |||
+ | <sxh java> | ||
+ | docker build --build-arg JAR_FILE=build/ | ||
+ | </ | ||
+ | |||
+ | == Build with Gradle == | ||
+ | |||
+ | You can build a tagged docker image with Gradle in one command: | ||
+ | |||
+ | <sxh java> | ||
+ | sudo su | ||
+ | ./gradlew bootBuildImage --imageName=springio/ | ||
+ | |||
+ | |||
+ | sudo docker images | ||
+ | |||
+ | </ | ||
+ | |||
+ | == And run == | ||
+ | |||
+ | <sxh java> | ||
+ | sudo docker run -p 8080:8080 springio/ | ||
+ | </ |