I'm working with properties in Spring and I have a doubt about the Properties
Valores.properties
estudiante.nombre=Antonio, Juan , Maria, Raquel
estudiante.edad=28,20,21,23
Now I have a class to develop the bean
public class Estudiante {
public Estudiante() {
}
public Estudiante(String nombre, Integer edad) {
super();
this.nombre = nombre;
this.edad = edad;
}
@Value("${estudiante.nombre}")
private String nombre;
@Value("${estudiante.edad}")
private Integer edad;
public Integer getEdad() {
return edad;
}
public void setEdad(Integer edad) {
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
@Override
public String toString() {
return '\n' +"Estudiante{" + "nombre=" + nombre + ", edad=" + edad + '}';
}
}
A java class to make the configuration
@Configuration
@PropertySource(value="classpath:valores.properties")
public class AppConfig {
@Value("#{'${estudiante.nombre}'.split(',')}")
private List<String> nombres;
@Value("#{'${estudiante.edad}'.split(',')}")
private List<Integer> edades;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
public List<String> getNombres() {
return nombres;
}
public List<Integer> getEdades() {
return edades;
}
public List<Estudiante> getListaStudents() {
List<Estudiante> listaStudents = new ArrayList<>();
for (int i= 0;i< nombres.size();i++){
listaStudents.add(new Estudiante(nombres.get(i),edades.get(i)));
}
return listaStudents;
}
}
And the main java class
public class Principal {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AppConfig appConfig = context.getBean(AppConfig.class);
System.out.println(appConfig.getListaStudents());
((ConfigurableApplicationContext)context).close();
}
}
The program works and the output is OK
[
Estudiante{nombre=Antonio, edad=28},
Estudiante{nombre= Juan , edad=20},
Estudiante{nombre= Maria, edad=21},
Estudiante{nombre= Raquel, edad=23}]
But I don't know if it is the right way to develop. I dón't like to build a method getListaStudents() in the AppConfig class to make a list of objets and I don't like to use the new() method in Spring
I think it's not a good idea but I don't know other way to solve. Any solution or any idea?
Thanks in advance
I think this is a proper approach with few improvements, but depending on the data size and requirements you may not want to load data from property files. Property files are usually used for configuration options such as database configurations for different environments, caching configurations etc..
In your AppConfig, you don't need to use SpringEL to parse a List
of Integer
s or String
s like this,
@Value("#{'${estudiante.nombre}'.split(',')}")
private List<String> nombres;
I would suggest to use something like this instead,
@Value("${estudiante.edad}") List<Integer> nombres
but for this to work you need to have one addtional bean configuration for Spring's ConversionService
@Bean
public ConversionService conversionService() {
return new DefaultConversionService();
}
This way Spring's conversion service will have default converters to convert a list of Strings or Integers so that you can avoid somewhat less readable #{'${estudiante.edad}'.split(',')}
in @Value
annotation.
Now you can use above @Value
to be used directly in a new bean to create a set of Students like this.
@Bean
public List<Estudiante> getStudents(
@Value("${estudiante.edad}") List<Integer> numbers,
@Value("${estudiante.nombre}") List<String> names) {
List<Estudiante> listaStudents = new ArrayList<Estudiante>();
for (int i= 0;i< numbers.size();i++){
listaStudents.add(new Estudiante(names.get(i), numbers.get(i)));
}
return listaStudents;
}
and you can inject list of Estudiante
s with @Resource
,
@Resource(name = "getStudents")
private List<Estudiante> estudiantes;
I don't see anything wrong with creating Estudiante
objects with new
keyword. Just as we use new
in other methods that are annotated with @Bean
this is a perfectly valid scenario. If you want, for whatever reason to avoid new
in creating Estudiante
, you can inject ApplicationContext and get Estudiante
with Estudiante studiante = applicationContext.getBean(Estudiante.class);
and don' forget to mark Estudiante
class with @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
I dón't like to build a method getListaStudents() in the AppConfig class to make a list of objects
As far as I know there is no simple and proper way to create a List
of Estudiante
objects as they need to have their own values. You can make student creation to its own configuration class such as EstudianteConfiguration
and import it to your main AppConfig
class with @Import annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With