Spring Boot 3: doc, test y prep. para impl.: Aula 5
This commit is contained in:
parent
f33e0b19ec
commit
320884a2a3
@ -0,0 +1,17 @@
|
|||||||
|
spring:
|
||||||
|
profile.active: prod
|
||||||
|
datasource:
|
||||||
|
url: ${DATASOURCE_URL}
|
||||||
|
username: ${DATASOURCE_USERNAME}
|
||||||
|
password: ${DATASOURCE_PASSWORD}
|
||||||
|
jpa:
|
||||||
|
show-sql: false
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: false
|
||||||
|
server:
|
||||||
|
error:
|
||||||
|
include-stacktrace: never
|
||||||
|
api:
|
||||||
|
security:
|
||||||
|
secret: ${JWT_SECRET}
|
@ -1,5 +1,5 @@
|
|||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://${TEST_DB_URL}?createDatabaseIfNotExist=true&serverTimezone=UTC
|
url: ${DATASOURCE_TEST_URL}
|
||||||
username: ${DB_USER}
|
username: ${DATASOURCE_USERNAME}
|
||||||
password: ${DB_PASS}
|
password: ${DATASOURCE_PASSWORD}
|
@ -1,13 +0,0 @@
|
|||||||
spring.datasource.url=jdbc:mysql://${DB_URL}
|
|
||||||
spring.datasource.username=${DB_USER}
|
|
||||||
spring.datasource.password=${DB_PASS}
|
|
||||||
|
|
||||||
spring.jpa.show-sql=true
|
|
||||||
spring.jpa.properties.hibernate.format_sql=true
|
|
||||||
|
|
||||||
server.error.include-stacktrace=never
|
|
||||||
|
|
||||||
api.security.secret=${JWT_SECRET}
|
|
||||||
|
|
||||||
spring.main.banner-mode=CONSOLE
|
|
||||||
spring.output.ansi.enabled=ALWAYS
|
|
@ -0,0 +1,22 @@
|
|||||||
|
spring:
|
||||||
|
profile.active: dev, test, prod
|
||||||
|
datasource:
|
||||||
|
url: ${DATASOURCE_URL}
|
||||||
|
username: ${DATASOURCE_USERNAME}
|
||||||
|
password: ${DATASOURCE_PASSWORD}
|
||||||
|
jpa:
|
||||||
|
show-sql: true
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
|
main:
|
||||||
|
banner-mode: CONSOLE
|
||||||
|
output:
|
||||||
|
ansi:
|
||||||
|
enabled: ALWAYS
|
||||||
|
server:
|
||||||
|
error:
|
||||||
|
include-stacktrace: never
|
||||||
|
api:
|
||||||
|
security:
|
||||||
|
secret: ${JWT_SECRET}
|
BIN
010_spring_boot/api_rest/api3/target/api-0.0.1-SNAPSHOT.jar
Normal file
BIN
010_spring_boot/api_rest/api3/target/api-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
@ -7,8 +7,9 @@
|
|||||||
- Hibernate
|
- Hibernate
|
||||||
[user guide](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html)
|
[user guide](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html)
|
||||||
|
|
||||||
Trabajando sobre el [proyecto](./jpa/tienda/src/main/java/com/latam/alura/tienda/)
|
Trabajando sobre el proyecto anterior
|
||||||
anterior
|
[tienda](./jpa/tienda/src/main/java/com/latam/alura/tienda/),
|
||||||
|
como [tienda2](./jpa/tienda2/src/main/java/com/latam/alura/tienda/)
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
erDiagram
|
erDiagram
|
||||||
@ -69,8 +70,8 @@ Web Console server running at http://127.0.1.1:8082 (only local connections)
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
En [pom.xml](./jpa/tienda2/pom.xml) cambiar la `url` para usar base de datos
|
En [persistence.xml](./jpa/tienda2/src/main/resources/META-INF/persistence.xml)
|
||||||
creada anteriormente
|
cambiar la `url` para usar base de datos creada anteriormente
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
...
|
...
|
||||||
|
@ -1218,4 +1218,185 @@ class ConsultaControllerTest {
|
|||||||
|
|
||||||
## Build del proyecto
|
## Build del proyecto
|
||||||
|
|
||||||
|
Migración de configuración de desarrollo `application.properties` (xml) a
|
||||||
|
`application.yml`. Con esto se tienen 3 perfiles de configuración:
|
||||||
|
|
||||||
|
- **DEV** [application.yml](./api_rest/api3/src/main/resources/application.yml)
|
||||||
|
- **TEST**
|
||||||
|
[application-test.yml](./api_rest/api3/src/main/resources/application-test.yml)
|
||||||
|
- **PROD**
|
||||||
|
[application-prod.yml](./api_rest/api3/src/main/resources/application-prod.yml)
|
||||||
|
|
||||||
|
Una forma de hacer la ***build*** del proyecto es en la pestañaa de maven en:
|
||||||
|
`api -> Lifecycle -> package` *click-secundario* y `Run Maven Build`.
|
||||||
|
|
||||||
|
Para correr la aplicación pasando manualmente la configuración y variables de
|
||||||
|
entorno:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
java -DDATASOURCE=jdbc:mysql//<DB_URL>/vollmed_api \
|
||||||
|
-DDATASOURCE_USERNAME=<USER> \
|
||||||
|
-DDATASOURCE_PASSWORD=<PASSWORD> \
|
||||||
|
-jar target/api-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
|
||||||
|
```
|
||||||
|
|
||||||
|
#### WAR
|
||||||
|
|
||||||
|
Los proyectos que utilizan Spring Boot generalmente usan el formato `jar` para
|
||||||
|
empaquetar la aplicación. Sin embargo, Spring Boot brinda soporte para empaquetar
|
||||||
|
en formato `war`, que era ampliamente utilizado en aplicaciones Java antiguas.
|
||||||
|
|
||||||
|
Para hacer el build del proyecto empaquete la aplicación en un archivo en formato
|
||||||
|
`war`, se deben realizar los siguientes cambios:
|
||||||
|
|
||||||
|
1. Agregar la etiqueta `<packaging>war</packaging>` al archivo `pom.xml` del
|
||||||
|
proyecto, y esta etiqueta debe ser hija de la etiqueta raíz `<project>`
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>med.voll</groupId>
|
||||||
|
<artifactId>api</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>api</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Agregar la siguiente dependencia:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Modificar en la clase principal del proyecto `ApiApplication` para heredar de
|
||||||
|
la clase `SpringBootServletInitializer`, y sobrescribir el método `configure`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ApiApplication extends SpringBootServletInitializer {
|
||||||
|
@Override
|
||||||
|
protected SpringApplicationBuilder configure(
|
||||||
|
SpringApplicationBuilder application) {
|
||||||
|
return application.sources(ApiApplication.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ApiApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ahora, al realizar el build del proyecto, se generará un archivo con la
|
||||||
|
extensión `war` en el directorio target, en lugar del `jar`.
|
||||||
|
|
||||||
|
#### GraalVM Native Image
|
||||||
|
|
||||||
|
Una de las características más destacadas de la versión 3 de Spring Boot es el
|
||||||
|
soporte para imágenes nativas, algo que reduce significativamente el consumo de
|
||||||
|
memoria y el tiempo de inicio de una aplicación. Algunos otros frameworks
|
||||||
|
competidores de Spring Boot, como ***Micronaut*** y ***Quarkus***, ya ofrecían
|
||||||
|
soporte para esta función.
|
||||||
|
|
||||||
|
De hecho, era posible generar imágenes nativas en aplicaciones con Spring Boot
|
||||||
|
antes de la versión 3, pero esto requería el uso de un proyecto llamado
|
||||||
|
***Spring Native*** que agregaba soporte para ello. Con la llegada de la versión
|
||||||
|
3 de Spring Boot, ya no es necesario utilizar este proyecto.
|
||||||
|
|
||||||
|
#### Native Image
|
||||||
|
|
||||||
|
Una imagen nativa es una tecnología utilizada para compilar una aplicación Java,
|
||||||
|
incluyendo todas sus dependencias, generando un archivo binario ejecutable que
|
||||||
|
puede ser ejecutado directamente en el sistema operativo sin necesidad de utilizar
|
||||||
|
la JVM. Aunque no se ejecute en una JVM, la aplicación también contará con sus
|
||||||
|
recursos, como la gestión de memoria, el recolector de basura y el control de la
|
||||||
|
ejecución de hilos.
|
||||||
|
|
||||||
|
> Documentación tecnología de [imágenes nativas](https://www.graalvm.org/native-image).
|
||||||
|
|
||||||
|
#### Native Imagen com Spring Boot 3
|
||||||
|
|
||||||
|
Una forma muy sencilla de generar una imagen nativa de la aplicación es mediante
|
||||||
|
un plugin de Maven, que debe incluirse en el archivo `pom.xml`:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.graalvm.buildtools</groupId>
|
||||||
|
<artifactId>native-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
```
|
||||||
|
|
||||||
|
Esta es la única modificación necesaria en el proyecto. Después de esto, la
|
||||||
|
generación de la imagen debe hacerse a través de la terminal, con el siguiente
|
||||||
|
comando de Maven que se ejecuta en el directorio raíz del proyecto:
|
||||||
|
`./mvnw -Pnative native:compile`
|
||||||
|
|
||||||
|
Este comando puede tardar varios minutos en completarse, lo cual es completamente
|
||||||
|
normal.
|
||||||
|
|
||||||
|
> **NOTE** Para ejecutar el comando anterior y generar la imagen nativa del
|
||||||
|
proyecto, es necesario que tener instalado en ***GraalVM*** *(una máquina virtual
|
||||||
|
Java con soporte para la función Native Image)* en una versión igual o superior
|
||||||
|
a **22.3**.
|
||||||
|
|
||||||
|
Después de que el comando anterior termine, se generará en la terminal un registro
|
||||||
|
como el siguiente:
|
||||||
|
|
||||||
|
```log
|
||||||
|
Top 10 packages in code area: Top 10 object types in image heap:
|
||||||
|
3,32MB jdk.proxy4 19,44MB byte[] for embedded resources
|
||||||
|
1,70MB sun.security.ssl 16,01MB byte[] for code metadata
|
||||||
|
1,18MB java.util 8,91MB java.lang.Class
|
||||||
|
936,28KB java.lang.invoke 6,74MB java.lang.String
|
||||||
|
794,65KB com.mysql.cj.jdbc 6,51MB byte[] for java.lang.String
|
||||||
|
724,02KB com.sun.crypto.provider 4,89MB byte[] for general heap data
|
||||||
|
650,46KB org.hibernate.dialect 3,07MB c.o.s.c.h.DynamicHubCompanion
|
||||||
|
566,00KB org.hibernate.dialect.function 2,40MB byte[] for reflection metadata
|
||||||
|
563,59KB com.oracle.svm.core.code 1,30MB java.lang.String[]
|
||||||
|
544,48KB org.apache.catalina.core 1,25MB c.o.s.c.h.DynamicHu~onMetadata
|
||||||
|
61,46MB for 1482 more packages 9,74MB for 6281 more object types
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
9,7s (5,7% of total time) in 77 GCs | Peak RSS: 8,03GB | CPU load: 7,27
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Produced artifacts:
|
||||||
|
/home/rodrigo/Desktop/api/target/api (executable)
|
||||||
|
/home/rodrigo/Desktop/api/target/api.build_artifacts.txt (txt)
|
||||||
|
================================================================================
|
||||||
|
Finished generating 'api' in 2m 50s.
|
||||||
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
[INFO] BUILD SUCCESS
|
||||||
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
[INFO] Total time: 03:03 min
|
||||||
|
[INFO] Finished at: 2023-01-17T12:13:04-03:00
|
||||||
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
```
|
||||||
|
|
||||||
|
La imagen nativa se genera en el directorio `target/`, junto con el archivo `jar`
|
||||||
|
de la aplicación, como un archivo ejecutable de nombre api.
|
||||||
|
|
||||||
|
A diferencia del archivo `jar`, que se ejecuta en la JVM mediante el comando
|
||||||
|
`java -jar`, la imagen nativa es un archivo binario y debe ejecutarse directamente
|
||||||
|
desde la terminal: `./target/api`
|
||||||
|
|
||||||
|
Al ejecutar el comando anterior se generará el registro de inicio de la
|
||||||
|
aplicación, que al final muestra el tiempo que tardó la aplicación en iniciarse:
|
||||||
|
|
||||||
|
```log
|
||||||
|
INFO 127815 --- [restartedMain] med.voll.api.ApiApplication : Started ApiApplication in 0.3 seconds (process running for 0.304)
|
||||||
|
```
|
||||||
|
|
||||||
|
La aplicación tardó menos de medio segundo en iniciarse, algo realmente
|
||||||
|
impresionante, ya que cuando se ejecuta en la JVM, a través del archivo `jar`,
|
||||||
|
este tiempo aumenta a alrededor de 5 segundos.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user