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/ | ||
| + | </ | ||
