yml spring_application_json example application java spring spring-boot properties-file

java - spring_application_json - spring properties file



Immutable @ConfigurationProperties (2)

Al final, si quieres un objeto inmutable también puedes "piratear" el setter que es

@ConfigurationProperties(prefix = "myapp") public class ApplicationProperties { private String someProperty; // ... other properties and getters public String getSomeProperty() { return someProperty; } public String setSomeProperty(String someProperty) { if (someProperty == null) { this.someProperty = someProperty; } } }

Obviamente, si la propiedad no es solo un String, es un objeto mutable, las cosas son más complicadas, pero esa es otra historia.

Aún mejor, puedes crear un contenedor de Configuración

@ConfigurationProperties(prefix = "myapp") public class ApplicationProperties { private final List<MyConfiguration> configurations = new ArrayList<>(); public List<MyConfiguration> getConfigurations() { return configurations } }

donde ahora la configuración es un clas sin

public class MyConfiguration { private String someProperty; // ... other properties and getters public String getSomeProperty() { return someProperty; } public String setSomeProperty(String someProperty) { if (someProperty == null) { this.someProperty = someProperty; } } }

y application.yml como

myapp: configurations: - someProperty: one - someProperty: two - someProperty: other

¿Es posible tener campos inmutables (finales) con la anotación @ConfigurationProperties Spring Boot? Ejemplo a continuación

@ConfigurationProperties(prefix = "example") public final class MyProps { private final String neededProperty; public MyProps(String neededProperty) { this.neededProperty = neededProperty; } public String getNeededProperty() { .. } }

Enfoques que he intentado hasta ahora:

  1. Crear un @Bean de la clase MyProps con dos constructores
    • Proporcionar dos constructores: vacío y con argumento de neededProperty
    • El bean se crea con new MyProps()
    • Resultados en el campo siendo null
  2. Usando @ComponentScan y @Component para proporcionar el bean MyProps .
    • Resultados en BeanInstantiationException -> NoSuchMethodException: MyProps.<init>()

La única forma en que lo tengo funcionando es proporcionando getter / setter para cada campo no final.


Tengo que resolver ese problema muy a menudo y utilizo un enfoque un poco diferente, que me permite usar variables final en una clase.

En primer lugar, mantengo toda mi configuración en un solo lugar (clase), por ejemplo, llamado ApplicationProperties . Esa clase tiene la anotación @ConfigurationProperties con un prefijo específico. También aparece en la anotación @EnableConfigurationProperties en la clase de configuración (o clase principal).

Luego proporciono mis ApplicationProperties como un argumento constructor y realizo la asignación a un campo final dentro de un constructor.

Ejemplo:

Clase principal :

@SpringBootApplication @EnableConfigurationProperties(ApplicationProperties.class) public class Application { public static void main(String... args) throws Exception { SpringApplication.run(Application.class, args); } }

Clase ApplicationProperties

@ConfigurationProperties(prefix = "myapp") public class ApplicationProperties { private String someProperty; // ... other properties and getters public String getSomeProperty() { return someProperty; } }

Y una clase con propiedades finales

@Service public class SomeImplementation implements SomeInterface { private final String someProperty; @Autowired public SomeImplementation(ApplicationProperties properties) { this.someProperty = properties.getSomeProperty(); } // ... other methods / properties }

Prefiero este enfoque por muchas razones diferentes, por ejemplo, si tengo que configurar más propiedades en un constructor, mi lista de argumentos de constructor no es "enorme" ya que siempre tengo un argumento ( ApplicationProperties en mi caso); si hay una necesidad de agregar más propiedades final , mi constructor permanece igual (solo un argumento) - eso puede reducir el número de cambios en otro lugar, etc.

Espero que le ayudará