Home > Blockchain >  Defining additional placeholder/property only in beans.xml
Defining additional placeholder/property only in beans.xml

Time:06-25

I have a list of strings, that i would like to define in beans.xml.

<util:list id="myFractions" value-type="java.lang.String">
    <value>#{ T(com.myapp.longname.verylong.WelcomeController).RED_FRACTION }</value>
    <value>#{ T(com.myapp.longname.verylong.WelcomeController).BLUE_FRACTION }</value>
    <value>#{ T(${my.prefix}).GREEN_FRACTION }</value>
</util:list>

It works fine, but each time I need to write the full qualified constant's name com.myapp.longname.verylong.WelcomeController. I would like to write it only once. One solution I have found is to replace it with a property like my.prefix so I can write only my short prefix instead of the real full path. But then I will need to pollute the global "namespace" with property that is only needed once. I would like to define a placeholder only for this list or at least only for this beans.xml file. I have already tried to define a property directly in beans.xml with PropertyPlaceholderConfigurer and it works, but then all my inital properties are not available anymore.

So how can I avoid to writing com.myapp.longname.verylong.WelcomeController each time in a list as a prefix and only define it once? Ideally something like

<util:list id="myFractions" value-type="java.lang.String">
    <define-local-placeholder name="my.prefix" value="com.myapp.longname.verylong.WelcomeController" />
    <value>#{ T(${my.prefix}).RED_FRACTION }</value>
    <value>#{ T(${my.prefix}).BLUE_FRACTION }</value>
    <value>#{ T(${my.prefix}).GREEN_FRACTION }</value>
</util:list>

CodePudding user response:

Try defining your prefix in properties file and use it in your beans.xml as shown here:

Best ways to deal with properties values in XML file in Spring, Maven and Eclipses

and here

Using Variable Substitution from Configuration Files in Spring

CodePudding user response:

A solution is to implement a FactoryBean, by extending the AbstractFactoryBean class:

package test;

import java.util.*;
import org.springframework.beans.factory.config.AbstractFactoryBean;

public class ConstantListFactoryBean extends AbstractFactoryBean<List<Object>>
{
    private Class<?> targetClass;
    private List<String> constantNames;

    public void setTargetClass(Class<?> targetClass)
    {
        this.targetClass = targetClass;
    }

    public void setConstantNames(List<String> constantNames)
    {
        this.constantNames = constantNames;
    }

    @Override
    public Class<List> getObjectType()
    {
        return List.class;
    }

    @Override
    protected List<Object> createInstance() throws Exception
    {
        ArrayList<Object> list = new ArrayList<Object>();
        for(String name : constantNames)
            list.add(targetClass.getField(name).get(null));
        return list;
    }
}

Here is a sample beans.xml that uses the ConstantListFactoryBean:

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

    <bean id="colors" >
        <property name="targetClass" value="test.Colors"/>
        <property name="constantNames">
            <list>
                <value>RED</value>
                <value>BLUE</value>
                <value>GREEN</value>
            </list>
        </property>
    </bean>
</beans>

And the sample class that holds the constants:

package test;

public class Colors
{
    public static final String RED = "red";
    public static final String BLUE = "blue";
    public static final String GREEN = "green";
}

And finally, some code that shows that it works:

import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        List colors = (List)context.getBean("colors");
        System.out.println(colors);
    }
}

Output:

[red, blue, green]
  • Related