java – 将.properties文件与Custom Bean Parser一起使用

我有一个AbstractSingleBeanDefinitionParser的自定义实现,允许我在我的spring配置中定义3D向量,其中包含的项目比其他方式要少.

<rbf:vector3d id="test_vector" delimeter=";" value="45;46;47"/>

这很好用,我已经使用它几个月没有任何问题.昨天我试图在.properties文件中定义这样的值:

在test.properties我有:

vector3d.value=1,2,3

在xml文件中我有:

<context:property-placeholder location="test.properties"/>
<rbf:vector3d id="test_vector_with_properties" delimeter="," value="${vector3d.value}"/>

当我尝试运行我的单元测试时,它崩溃了,我得到了这个异常:

Caused by: java.lang.NumberFormatException: For input string: "${vector3d.value}"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
    at java.lang.Double.parseDouble(Double.java:510)
    at scala.collection.immutable.StringLike$class.toDouble(StringLike.scala:234)
    at scala.collection.immutable.StringOps.toDouble(StringOps.scala:31)
    at rb.foundation.spring.xml.Vector3DBeanDefinitionParser$$anonfun$1.apply(Vector3DBeanDefinitionParser.scala:25)

当我将.properties文件用于普通bean时,它工作得很好,这使我相信在我的解析器实现中我忽略了一些微妙之处.它是用scala编写的,但你应该能够遵循它:

class Vector3DBeanDefinitionParser extends AbstractSingleBeanDefinitionParser
{
  override def getBeanClass(element : Element) = classOf[Vector3D]

  override def doParse(element: Element, builder: BeanDefinitionBuilder)
  {
    val delim = element.getAttribute("delimeter")
    val value = element.getAttribute("value")

    val values = value.split(delim).map(_.toDouble)

    builder.addConstructorArgValue(values(0))
    builder.addConstructorArgValue(values(1))
    builder.addConstructorArgValue(values(2))
  }
}

如果有必要,我很乐意添加密钥替换,我只需要知道在哪里/如何做.

想法?

解决方法:

所以这不起作用的原因是你的BeanDefinitionParser在解析属性占位符之前运行很多.我理解的简单概述:

> BeanDefinitionParsers将XML解析为内存中的BeanDefinition对象
>然后将BeanDefinitions加载到BeanFactory中
> BeanFactoryPostProcessors(包括属性占位符配置程序)在bean定义上执行
> bean是从bean定义创建的

(当然其他事情也会发生,但这些都是相关的步骤.)

因此,为了将已解析的属性值放入Vector3D对象中,我认为在BeanFactoryPostProcessors运行之前,您将不得不延迟指定Vector3D构造函数的参数.我遇到的一种方法是让你的BeanDefinitionParser为Spring FactoryBean而不是Vector3D本身构造一个bean定义.然后,您在Vector3DBeanDefinitionParser中当前具有的矢量值的拆分需要在FactoryBean实现中.

对不起,我对Scala不太熟悉所以这将是Java.

FactoryBean类看起来像这样:

import org.springframework.beans.factory.FactoryBean;

public class Vector3DFactoryBean implements FactoryBean<Vector3D> {
    private String delimiter;
    private String value;
    private transient Vector3D instance;

    public String getDelimiter() { return delimiter; }
    public void setDelimiter(String delimiter) { this.delimiter = delimiter; }
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }

    @Override
    public Vector3D getObject() {
        if (instance == null) {
            String[] values = value.split(delimiter);
            instance = new Vector3D(
                                    Double.parseDouble(values[0]),
                                    Double.parseDouble(values[1]),
                                    Double.parseDouble(values[2])
                                   );
        }
        return instance;
    }
    @Override
    public Class<?> getObjectType() {
        return Vector3D.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
}

然后你的Vector3DBeanDefinitionParser只会将分隔符和值不变地传递给Vector3DFactoryBean bean定义:

class Vector3DBeanDefinitionParser extends AbstractSingleBeanDefinitionParser
{
  override def getBeanClass(element : Element) = classOf[Vector3DFactoryBean]

  override def doParse(element: Element, builder: BeanDefinitionBuilder)
  {
    val delim = element.getAttribute("delimeter")
    val value = element.getAttribute("value")

    builder.addPropertyValue("delimiter", delim)
    builder.addPropertyValue("value", value)
  }
}

然后,当占位符属性configurer运行时,它应该解析Vector3DFactoryBean bean定义中的属性值.当最终从bean定义创建bean时,Vector3DFactoryBean将解析向量值并创建Vector3D对象.

原文地址:https://codeday.me/bug/20190625/1287941.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 TwemojiTwemoji是Twitter开源的其完整的Emoji表情图片。开发者可以去GitHub下载完整的表情库,并把这些表情加入到自己的应用或网页中。使用示例:var i = 0;twemoji.parse(  ’emoji, m\u276
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即两个对象在内存中的首地址;equals比较字符串中所包含的内容是否相同。publicstaticvoidmain(String[]args){​ Strings1="abc"; Strings2=newString("abc");​ System.out.println(s1==s2)
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么使用”吧!语法scala...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相信很多人在Scala是一种什么语言问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相信很多人在Scala Trait怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日常操作中,相信很多人在Scala类型检查与模式匹配怎么使用问题上存在疑惑,小编查阅了各式资料,整理...
这篇文章主要介绍“scala中常用但不常见的符号有哪些”,在日常操作中,相信很多人在scala中常用但不常见的符号有哪些问题上存在疑惑,小编查阅了各式资料,整理...
本篇内容主要讲解“Scala基础知识有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala基础知识有哪些”...
本篇内容介绍了“scala基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容介绍了“Scala下划线怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容主要讲解“Scala提取器怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala提取器怎么使用”...
这篇文章主要讲解了“Scala基础语法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala基础语法有...
本篇内容主要讲解“Scala方法与函数怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala方法与函数怎...
这篇文章主要讲解了“scala条件控制与循环怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala条...
这篇文章主要介绍“scala函数怎么定义和调用”,在日常操作中,相信很多人在scala函数怎么定义和调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操
这篇文章主要介绍“scala如何声明变量”,在日常操作中,相信很多人在scala如何声明变量问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对...
这篇文章主要讲解了“scala的Map和Tuple怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala的Ma...
这篇文章主要介绍“scala的隐式参数有什么作用”,在日常操作中,相信很多人在scala的隐式参数有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
本篇内容主要讲解“Scala怎么进行文件写操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么进行文件...
这篇文章主要讲解了“Scala怎么声明数组”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala怎么声明数组...