Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从属性文件转换数据并设置为列表属性(使用PropertyPlaceHolderConfigure)?_Java_Spring_Properties File - Fatal编程技术网

Java 如何从属性文件转换数据并设置为列表属性(使用PropertyPlaceHolderConfigure)?

Java 如何从属性文件转换数据并设置为列表属性(使用PropertyPlaceHolderConfigure)?,java,spring,properties-file,Java,Spring,Properties File,我有一个实体: public class Auditorium { private Integer id; private String name; private Integer numberOfSeats; private List<String> vipSeats; public Auditorium(String name, Integer numberOfSeats, List<String> vipSeats) {

我有一个实体:

public class Auditorium {
    private Integer id;
    private String name;
    private Integer numberOfSeats;
    private List<String> vipSeats;

    public Auditorium(String name, Integer numberOfSeats, List<String> vipSeats) {
        this.name = name;
        this.numberOfSeats = numberOfSeats;
        this.vipSeats = vipSeats;
    }
我有几个不同的文件,我想创建不同的
Auditorium
bean

下面是来自
spring.xml
的片段:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:auditorium1.properties</value>
            <value>classpath:auditorium2.properties</value>
            <value>classpath:auditorium3.properties</value>
        </list>
    </property>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="systemPropertiesMode">
        <util:constant
                static-field="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    </property>
</bean>

<util:list id="auditorium1" value-type="java.lang.String">
    <value></value>
</util:list>

<util:list>
    <bean class="net.lelyak.edu.entity.Auditorium"
          p:name="${auditorium1.name}" p:numberOfSeats="${auditorium1.number-of-seats}" p:vipSeats="${auditorium1.vip-seats}"/>
</util:list>

类路径:auditorium1.properties
类路径:auditorium2.properties
类路径:auditorium3.properties
但我犯了一个错误:

因为未找到匹配的构造函数

更好的方法是
列出vipSeats
。在这种情况下可能吗


如何解决这个问题?

这里有两个方面需要讨论,所以让我们一次讨论一个:

1) IJ(intellijidea的缩写)建议,根据您的bean声明,Spring将尝试调用一个无参数构造函数,该构造函数显然不存在,因为您已经定义了
公共礼堂(字符串名称、整数numberOfSeats、列表vipSeats)

因此,您可以将其配置为调用上述构造函数并传递正确的参数,如下所示:


除此之外,Spring注入列表不需要特殊处理,正如您在下面的日志片段中所看到的,它由一个简单的
toString()
IJ自动生成方法输出:

16:13:56.569 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.example.Auditorium#0'
16:13:56.601 [main] DEBUG com.example.Auditorium - Auditorium{id=null, name='yellow hall', numberOfSeats=150, vipSeats=[1,2,3,4,5,6,7,8,9]}
12:20:34.037 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'auditorium'
12:20:34.038 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'auditorium'
12:20:34.045 [main] DEBUG o.s.c.a.CommonAnnotationBeanPostProcessor - Found init method on class [com.example.Auditorium]: private void com.example.Auditorium.doAfterConstruction()
12:20:34.045 [main] DEBUG o.s.c.a.CommonAnnotationBeanPostProcessor - Registered init method on class [com.example.Auditorium]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@1ec4fbf0
12:20:34.060 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Registered injected element on class [com.example.Auditorium]: AutowiredFieldElement for private java.lang.String com.example.Auditorium.name
12:20:34.060 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Registered injected element on class [com.example.Auditorium]: AutowiredFieldElement for private java.lang.Integer com.example.Auditorium.numberOfSeats
12:20:34.060 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Registered injected element on class [com.example.Auditorium]: AutowiredFieldElement for private java.util.List com.example.Auditorium.vipSeats
12:20:34.060 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'auditorium' to allow for resolving potential circular references
12:20:34.062 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Processing injected element of bean 'auditorium': AutowiredFieldElement for private java.lang.String com.example.Auditorium.name
12:20:34.067 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Processing injected element of bean 'auditorium': AutowiredFieldElement for private java.lang.Integer com.example.Auditorium.numberOfSeats
12:20:34.072 [main] DEBUG o.s.b.f.annotation.InjectionMetadata - Processing injected element of bean 'auditorium': AutowiredFieldElement for private java.util.List com.example.Auditorium.vipSeats
12:20:34.084 [main] DEBUG o.s.c.a.CommonAnnotationBeanPostProcessor - Invoking init method on bean 'auditorium': private void com.example.Auditorium.doAfterConstruction()
12:20:34.085 [main] DEBUG com.example.Auditorium - Auditorium{id=null, name='yellow hall', numberOfSeats=150, vipSeats=[1,2,3,4,5,6,7,8,9]}
12:20:34.094 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'auditorium'


2) 我看到您正试图使用传递参数给构造函数,但是在bean实例化之后,它被用来设置属性。您可以使用来实现与使用
标记相同的效果,并且不太冗长(请注意,根据spring文档,p&c名称空间未在XSD文件中定义,仅存在于spring的核心中):


以及这次为两个定义生成的日志片段:

16:26:52.258 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.example.Auditorium#0'
16:26:52.287 [main] DEBUG com.example.Auditorium - Auditorium{id=null, name='yellow hall', numberOfSeats=150, vipSeats=[1,2,3,4,5,6,7,8,9]}
...
16:26:52.287 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.example.Auditorium#1'
16:26:52.288 [main] DEBUG com.example.Auditorium - Auditorium{id=null, name='yellow hall', numberOfSeats=150, vipSeats=[1,2,3,4,5,6,7,8,9]}


注意:根据您使用的Spring版本和您的需要,它可能也值得检查。这可能是个人的偏好,但我发现它们更干净、更易于维护,IJ对这两种配置都有出色的Spring支持



特殊要求更新:简要说明

首先,它取决于您的项目设置,无论您使用的是基本Spring Core还是Spring Boot,等等。对于本介绍:我将从您现在的位置开始:

启用组件扫描,以便Spring能够发现和创建您的组件、服务等


那就换个班。如果您不需要在构造函数中执行任何其他操作,那么我们可以简单地删除它并对字段进行注释在注释字段时请考虑到Spring只有在实例化bean之后才能填充字段,因此在构造函数中使用then很可能会导致NPE。在这种情况下,您可以使用
@PostConstruct

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

@Component
public class Auditorium {
    private static final Logger log = LoggerFactory.getLogger(Auditorium.class);
    private Integer id;

    @Value("${auditorium1.name}")
    private String name;

    @Value("${auditorium1.number-of-seats}")
    private Integer numberOfSeats;

    @Value("${auditorium1.vip-seats}")
    private List<String> vipSeats;

    @PostConstruct
    private void doAfterConstruction() {
        log.debug(this.toString());
    }

    @Override
    public String toString() {
        return "Auditorium{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", numberOfSeats=" + numberOfSeats +
                ", vipSeats=" + vipSeats +
                '}';
    }
}
或者,如果您想保留构造函数,我们将其标记为
@Autowired
,并对参数进行注释:

@Component
public class Auditorium {
    private static final Logger log = LoggerFactory.getLogger(Auditorium.class);
    private Integer id;
    private String name;
    private Integer numberOfSeats;
    private List<String> vipSeats;

    @Autowired
    public Auditorium(@Value("${auditorium1.name}") String name,
                      @Value("${auditorium1.number-of-seats}") Integer numberOfSeats,
                      @Value("${auditorium1.vip-seats}") List<String> vipSeats) {
        this.name = name;
        this.numberOfSeats = numberOfSeats;
        this.vipSeats = vipSeats;
        log.debug(this.toString());
    }
}

IJ
是什么意思?@nazar\u艺术很好。它是IntelliJ Idea的缩写,我从XML定义屏幕截图中识别出了主题。我会更新答案让它更清楚。感谢您在此演示如何使用
注释方法的示例。这对我来说非常有用,因为我使用的是“Spring 3.2.13”。@nazar_art这是一个非常广泛的主题。看看我提供的和其他的。他们更适合这份工作,如果你有困难,你肯定会找到答案的。但是为了让你开始,我在你最初的项目的基础上添加了一个简短的示例。干杯!您知道如何保存与套装完全相同的
vipSeats
。因为现在它被保存为一个字符串
1,2,3,4,5
@Component
public class Auditorium {
    private static final Logger log = LoggerFactory.getLogger(Auditorium.class);
    private Integer id;
    private String name;
    private Integer numberOfSeats;
    private List<String> vipSeats;

    @Autowired
    public Auditorium(@Value("${auditorium1.name}") String name,
                      @Value("${auditorium1.number-of-seats}") Integer numberOfSeats,
                      @Value("${auditorium1.vip-seats}") List<String> vipSeats) {
        this.name = name;
        this.numberOfSeats = numberOfSeats;
        this.vipSeats = vipSeats;
        log.debug(this.toString());
    }
}
12:29:09.492 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'auditorium'
12:29:09.492 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'auditorium'
12:29:09.525 [main] DEBUG com.example.Auditorium - Auditorium{id=null, name='yellow hall', numberOfSeats=150, vipSeats=[1,2,3,4,5,6,7,8,9]}
12:29:09.526 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'auditorium' to allow for resolving potential circular references
12:29:09.548 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'auditorium'