【问题标题】:Can one use an Enum within a @Value可以在@Value 中使用枚举吗
【发布时间】:2017-12-12 20:42:24
【问题描述】:

我正在尝试解决一个问题。我们将我们的属性存储在数据库中,当我们的应用程序启动时,我们在整个代码中都有多个“@Value”。如果有人忘记将该属性放入数据库,它不会让应用程序启动。因此,我正在寻找一种解决方案来检查应用程序所期望的所有属性是否都存在。我当前的路径是从 applicationContext.xml 使用它-“AppPropertiesConfigurer”扩展了 PropertySourcesPlaceholderConfigurer 并实现了 BeanPostProcessor

<!-- Configure CH Properties -->
<bean id="applicationPropertyConfigurer" class="com.chw.base.spring.AppPropertiesConfigurer"
    depends-on="propertiesSessionFactory">
    <property name="applicationCode" value="xyz" />
    <property name="sessionFactory" ref="propertiesSessionFactory" />
    <property name="locations">
        <list>
            <value>/WEB-INF/build.properties</value>
        </list>
    </property>
</bean>

我所做的是创建这个类来扩展上面的那个类。这将检查是否所有属性都已加载,如果没有,则会记录错误消息。

import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.chg.base.util.CHGProperties;
import com.chw.base.spring.ChwPropertiesConfigurer;
import com.chw.dbobjects.manager.PropertiesId;


public class MyAppPropertiesConfigurer
        extends AppPropertiesConfigurer
{

    private static Log aLog = LogFactory.getLog(PxiPropertiesConfigurer.class);
    private final String aPropertyNotValid = "Property not valid";
    private final String aPropertyNotFound = "Property not found";
    private HashMap<String, String> aPropertiesMap = new HashMap();

    @Override
    protected void 
    loadProperties(Properties pProps)
    throws IOException
    {
        super.loadProperties(pProps);

        getProperties();

        int count = 1;
        for (PropertiesId properties : PropertiesId.values())
        {
            aLog.error("Property " + count + ":" + properties.getPropertiesName());
            testProperty(properties.getPropertiesName());
        }
        try
        {
            Thread.sleep(60000);
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public final void testProperty(String pKey)
    {
        Properties lPropertiesList = CHGProperties.getMappedProperties();
        Object lObject = lPropertiesList.getProperty(pKey);
        if (lObject == null)
        {
            aLog.error(aPropertyNotFound + " " + pKey);
        }
    }
}

上面有一个对“PropertiesId”的引用——就是这个枚举。

public enum PropertiesId
{
    CLEAR_VTD_FLAG("clear.vtd.flag"),
    MAIL_FROM("app.mailfrom"),
    FAKE_PROPERTY("fake.property");

    private final String propertiesName;

    PropertiesId(String propertiesName) 
    { 
        this.propertiesName = propertiesName;
    }

    public String getPropertiesName()
    {
        return propertiesName;
    }
}

现在在另一个类中,我有许多在整个应用程序中使用的@Values。我们创建了一个类来容纳所有这些以帮助进行单元测试,但事后看来,将它们全部放在一个地方而不是分散在代码中是很好的。所以,我想这样做,但 Eclipse 抱怨它。有没有更简单的方法来做到这一点?

@Value("${" + PropertiesId.CLEAR_VTD_FLAG + "}")
private boolean aClearVtdFlag;

@Value("${" + PropertiesId.CLEAR_VTD_FLAG + "}")
private boolean aFake;
@Value("${clear.vtd.flag:true}")
private boolean aClearVtdFlag;

也许有另一种方法可以验证应用程序的所有属性是否存在?

谢谢,迈克尔

PS:运行 Spring 3.2

【问题讨论】:

  • 几个这里的东西:1)注释的值必须是编译时常量。连接不被解释为编译时常量。 2) 你为什么卡在旧版本的 Spring 上?
  • @Makoto 连接编译时常量,但这些是枚举,而不是字符串。
  • 会有比上述方法更好的做法吗?

标签: java spring enums


【解决方案1】:

使用 SpEL,您可以通过调用它来绕过枚举而不是常量。确保你实际上得到了一个类似布尔值的值,否则你会遇到问题;这只会返回文本CLEAR_VTD_FLAG

@Value("#{T(com.example.pkg.to.your.enum.PropertiesId).CLEAR_VTD_FLAG}")
private boolean aClearVtdFlag;

【讨论】:

  • 我试过这个,但这是我得到的错误'weblogic.application.ModuleException: java.lang.IllegalArgumentException: Cannot convert value of type [com.someapp.manager.PropertiesId] to required类型 [boolean]:PropertyEditor [org.springframework.beans.propertyeditors.CustomBooleanEditor] 返回了 [com.someapp.manager.PropertiesId] 类型的不适当值我认为它会返回 CLEAR_VTD_FLAG 的字符串而不是注入布尔值。 ..
  • @schu777:“请确保您实际上得到了一个类似布尔值的值,否则您会遇到问题;这只会返回文本 CLEAR_VTD_FLAG 。”
【解决方案2】:

Spring 按名称映射@Value("...")enum,例如:

application.properties

enum.name1="Marry"
enum.name2="John"

枚举类

public enum Name {
    Marry,
    John;
}

你想用的地方

@Value("enum.name1")
Name name1; //name1 == Mary;
@Value("enum.name2")
Name name2; //name2 == John;

只注意它们区分大小写。

更好的方法是使用@ConfigurationProperties

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2015-03-02
    • 1970-01-01
    • 2022-01-02
    • 2017-11-11
    • 1970-01-01
    相关资源
    最近更新 更多