当前位置: 首页 > 知识库问答 >
问题:

如何将数据从属性文件转换为列表属性(使用PropertyPlaceHolderConfigureer)?

闾丘文昌
2023-03-14

我有一个实体:

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实例,如:

auditorium1.name=yellow hall
auditorium1.number-of-seats=150
auditorium1.vip-seats=1,2,3,4,5,6,7,8,9

我有几个不同的文件,我想创建不同的auditoriumbean。

<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>

更好的是有列表 vipseats 。在这种情况下有可能吗?

如何解决这个麻烦?

共有1个答案

杨骏
2023-03-14

这里有两个方面要涉及,所以让我们一次一个:

1)IJ(IntelliJ Idea的缩写)建议根据bean声明,Spring将尝试调用一个无参数的构造函数,由于您已经定义了Public Auditorium(String name,Integer NumberOfSeates,List VIPSeates) ,因此该构造函数显然不存在。

因此,您可以根据spring文档将其配置为调用上面提到的传递正确参数的构造函数:

<bean class="com.example.Auditorium">
    <constructor-arg name="name" value="${auditorium1.name}"/>
    <constructor-arg name="numberOfSeats" value="${auditorium1.number-of-seats}"/>
    <constructor-arg name="vipSeats" value="${auditorium1.vip-seats}"/>
</bean>
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]}

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

<beans ...
       xmlns:c="http://www.springframework.org/schema/c"
       ...>

    <bean id="myAuditorium" class="com.example.Auditorium" c:name="${auditorium1.name}" c:numberOfSeats="${auditorium1.number-of-seats}" c:vipSeats="${auditorium1.vip-seats}"/>

和为这两个定义生成的日志段:

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 Core还是Spring Boot,等等。对于本文的介绍,我将从您现在的位置开始:

启用组件扫描,这样Spring就可以发现并创建您的组件、服务等

<?xml version="1.0" encoding="UTF-8"?>
<beans ...
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="...
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.example" />
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 +
                '}';
    }
}
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'
@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'
 类似资料:
  • 作为一个简化的例子,考虑这个有两个字段的表。一个是字符串,另一个是XML。 Source=“MediaConversions” 现在我想查询该表,并将结果作为json,但也要一次性将XML转换为json。 导致 [{"Source":"媒体转换","OrderParameter":" 但我想把它转换成: [{"Source":"MediaConversion","OrderParameter":{

  • 问题内容: 是否可以某种方式用于属性值,而不是替换内部HTML内容?例如这个简单的指令 并用作 我希望它翻译成 有什么办法吗,还是我必须使用属性而不是包含? 这是 摆弄例子 问题答案: 像这样: 摆弄。

  • 我已经建立了一个管道,在microsoft azure管道中运行我的测试。在我的本地机器上,这工作正常,文件位于我的计算机上的gradle系统目录中: 这是我的: 据我所知,由jetifier从文件。 输出: 下面是我组装调试和测试单元测试的azure-pipelines.yml的一部分: 我在这篇文章、这篇文章和这篇文章中尝试了解决方案,但没有结果。jar文件大4mb,是代码存储库中唯一的文件,

  • 我在尝试添加

  • null null 我用一个单独的脚本编写了整个测试用例,并首先在groovy控制台上测试了它。当我开始将它转换为soapUI,并使用该属性将数据从步骤2“传输”到步骤5时,我出现了问题,因为我似乎无法将Arraylist放入属性(请参见下面的错误消息)。 现在我感到困惑的是,这是不可能的,因为我可以很容易地将SQL实例放在属性中: 因此,我如何将我的数组(填充了对象)从步骤2传输到步骤5,以便与

  • 我有一个JSON格式。 我希望将其转换为以下格式的对象: