Java 将.properties文件与自定义Bean解析器一起使用
我有一个AbstractSingleBeanDefinitionParser的自定义实现,它允许我在spring配置中定义3D向量,只需很少的。。。不需要的仪式Java 将.properties文件与自定义Bean解析器一起使用,java,spring,scala,customization,javabeans,Java,Spring,Scala,Customization,Javabeans,我有一个AbstractSingleBeanDefinitionParser的自定义实现,它允许我在spring配置中定义3D向量,只需很少的。。。不需要的仪式 <rbf:vector3d id="test_vector" delimeter=";" value="45;46;47"/> 在xml文件中,我有: <context:property-placeholder location="test.properties"/> <rbf:vector3d id="
<rbf:vector3d id="test_vector" delimeter=";" value="45;46;47"/>
在xml文件中,我有:
<context:property-placeholder location="test.properties"/>
<rbf:vector3d id="test_vector_with_properties" delimeter="," value="${vector3d.value}"/>
当我为普通bean使用.properties文件时,它工作得非常好,这使我相信在我的解析器实现中有一个我忽略的微妙之处。它是用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在解析属性占位符之前运行了很多时间。我所理解的简单概述:
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;
}
}
然后,当占位符属性配置器运行时,它应该解析Vector3DFactoryBean定义中的属性值。当最终从bean定义创建bean时,Vector3DFactoryBean将解析向量值并创建Vector3D对象。是否尝试向“test.properties”添加完整路径?如果没有帮助,请尝试使用检查日志。另一个建议是,使用${…}。很好,这正是我想要的。我在工厂中没有使用“实例”就实现了它,但除此之外,它工作得很好(在scala中也是如此!)。享受您的100点声誉积分。。。不要把它们都花在同一个地方!谢谢,我很高兴能帮上忙!
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))
}
}
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;
}
}
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)
}
}