在Spring中使用属性来创建对象列表

时间:2016-04-02 22:46:10

标签: java spring properties

我正在使用Spring中的属性,我对属性

有疑问

Valores.properties

estudiante.nombre=Antonio, Juan , Maria, Raquel
estudiante.edad=28,20,21,23

现在我有一个开发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 + '}';
    }

}

进行配置的java类

@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;
    }

}

主java类

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();
    }

}

程序正常,输出正常

[
Estudiante{nombre=Antonio, edad=28}, 
Estudiante{nombre= Juan , edad=20}, 
Estudiante{nombre= Maria, edad=21}, 
Estudiante{nombre= Raquel, edad=23}]

但我不知道这是否是正确的发展方式。我不想在AppConfig类中构建一个方法getListaStudents()来创建一个objets列表,我不喜欢在Spring中使用new()方法

我认为这不是一个好主意,但我不知道其他解决办法。 任何解决方案或任何想法?

提前致谢

2 个答案:

答案 0 :(得分:2)

我认为这是一种很少改进的正确方法,但根据数据大小和要求,您可能想要从属性文件加载数据。属性文件通常用于配置选项,例如不同环境的数据库配置,缓存配置等。

在AppConfig中,您无需使用SpringEL来解析fortune ListInteger这样的内容,

String

我建议改用这样的东西,

@Value("#{'${estudiante.nombre}'.split(',')}")
private List<String> nombres;

但要实现这一点,您需要为Spring ConversionService

设置一个附加bean配置
@Value("${estudiante.edad}") List<Integer> nombres

这样,Spring的转换服务将使用默认转换器来转换字符串或整数列表,以便在@Bean public ConversionService conversionService() { return new DefaultConversionService(); } 注释中避免使用#{'${estudiante.edad}'.split(',')}的可读性较低。

现在,您可以使用以上@Value直接在新bean中使用,以创建一组像这样的学生。

@Value

您可以使用@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; }

注入Estudiante的列表
@Resource

使用@Resource(name = "getStudents") private List<Estudiante> estudiantes; 关键字创建Estudiante个对象时,我认为没有任何问题。正如我们在使用new注释的其他方法中使用new一样,这是完全有效的方案。如果您想以任何理由避免@Bean创建new,您可以注入ApplicationContext并使用Estudiante获取Estudiante并且不要忘记标记{ {1}} Estudiante studiante = applicationContext.getBean(Estudiante.class);

的课程
  

我不想在AppConfig类中构建方法getListaStudents()来创建对象列表

据我所知,没有简单且正确的方法来创建Estudiante @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)List个对象,因为它们需要拥有自己的值。您可以将学生创建到自己的配置类,例如Estudiante,并使用@Import注释将其导入到主EstudianteConfiguration类。

答案 1 :(得分:0)

Uooohh ..这是一个很好的解决方案。 感谢您的时间Bunti(并感谢其他用户的修订)

我已根据您的建议制定解决方案,购买我有问题要抓住并拆分属性文件的值。

新课程(包含建议)在这里

@Configuration
@PropertySource(value="classpath:valores.properties")
public class AppConfig {

    @Resource(name = "getStudents")
    private List<Estudiante> estudiantes;

    public List<Estudiante> getEstudiantes() {  
        return estudiantes;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public ConversionService conversionService() {
        return new DefaultConversionService();
    }

    @Bean
    public List<Estudiante> getStudents(
        @Value("${estudiante.nombre}")List<String> nombres,
        @Value("${estudiante.edad}") List<Integer> numbers
        ) {

        List<Estudiante> listaStudents = new ArrayList<>();
        for (int i= 0;i< nombres.size();i++){
            listaStudents.add(new Estudiante(nombres.get(i),numbers.get(i)));
            //listaStudents.add(new Estudiante(nombres.get(i)));
        }
        return listaStudents;
    }
}

跑步,我有几个例外,但我认为这是同样的问题

只捕获属性文件的String值(在本例中为name中的值)系统写入

[Estudiante{nombre=Antonio, Juan , Maria, Raquel, edad=null}]

为了允许这个输出,我已经注释了对Integer Values的所有引用(所以,age / edad是null ...没问题)

真的,它没有拆分属性File,字符串值是“a,b,c,d ......”(大小是1)

所以,当我使用属性文件

estudiante.nombre=Antonio, Juan , Maria, Raquel
estudiante.edad=28,20,21,23

并捕获String和Integer有一个异常

Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': 
Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'getStudents' defined in test.AppConfig: 
Unsatisfied dependency expressed through constructor argument with index 1 of type [java.util.List]: : 
Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; nested exception is java.lang.NumberFormatException: 
For input string: "28,20,21,23"; nested exception is org.springframework.beans.TypeMismatchException: 
Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; 
nested exception is java.lang.NumberFormatException: For input string: "28,20,21,23"

例外是合乎逻辑的。我期待一个数字来解析...但是我抓住了“28,20,21,23”......并且没有转换为数字。

因此,convert方法理解由?

分隔的值列表