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:
|
||||
datasource:
|
||||
url: jdbc:mysql://${TEST_DB_URL}?createDatabaseIfNotExist=true&serverTimezone=UTC
|
||||
username: ${DB_USER}
|
||||
password: ${DB_PASS}
|
||||
url: ${DATASOURCE_TEST_URL}
|
||||
username: ${DATASOURCE_USERNAME}
|
||||
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
|
||||
[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/)
|
||||
anterior
|
||||
Trabajando sobre el proyecto anterior
|
||||
[tienda](./jpa/tienda/src/main/java/com/latam/alura/tienda/),
|
||||
como [tienda2](./jpa/tienda2/src/main/java/com/latam/alura/tienda/)
|
||||
|
||||
```mermaid
|
||||
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
|
||||
creada anteriormente
|
||||
En [persistence.xml](./jpa/tienda2/src/main/resources/META-INF/persistence.xml)
|
||||
cambiar la `url` para usar base de datos creada anteriormente
|
||||
|
||||
```xml
|
||||
...
|
||||
|
@ -1218,4 +1218,185 @@ class ConsultaControllerTest {
|
||||
|
||||
## 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