长话短说:
有没有办法将${my.property}
得到的字符串解释为@Value
注释中的SpEL表达式而不使用转换器,例如像@Value("#{${my.property}}
)这样的东西?
我有一个抽象工厂(简化),它允许我构建一些属于我系统配置的公共对象。
@Component
public class Factory {
public Product makeVal(int x) { return new Product(5); }
}
为了更灵活,我想让用户在app.properties
文件中编写SpEL表达式,以便直接访问工厂:
my.property = @Factory.makeVal(12)
现在,在需要此属性的类中,为了实现我的目标,我编写了以下代码。
@Value("#{${my.property}}")
private Product obj;
我认为${my.property}
将进行宏扩展,然后由#{}
作为相应的SpEL表达式进行评估,@Factory.makeVal(12)
在上面的示例中。不幸的是,情况并非如此,加载Spring上下文导致错误,表示无法将字符串(属性的值${my.property}
)转换为目标类型{{1} }。
现在,我通过编写一个实现Product
的类来解决这个问题,但是由于我需要通过实例化Converter<String, Product>
以编程方式将字符串计算为SpEL表达式,因此它非常复杂。上。
但是有更简单的解决方案吗?是否有一个SpEL表达式放在ExpressionParser
注释中,这样我就可以简单地将@Value
评估为SpEL表达式了吗?
答案 0 :(得分:2)
可能只是在属性值中用@Factory
替换factory
。这个测试通过我:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { SpelTest.Config.class })
public class SpelTest
{
@Value("#{${my.property}}")
Product _product;
@Test
public void evaluating_spel_from_property_value() throws Exception
{
Assert.assertEquals(1234, _product.value);
}
@Component
public static class Factory
{
public Product makeVal(int x) { return new Product(x); }
}
public static class Product
{
public final int value;
public Product(final int value) { this.value = value; }
}
@Configuration
@ComponentScan(basePackageClasses = SpelTest.class)
public static class Config
{
@Bean
public Factory factory() { return new Factory(); }
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
final PropertySourcesPlaceholderConfigurer psc = new PropertySourcesPlaceholderConfigurer();
final MutablePropertySources sources = new MutablePropertySources();
sources.addFirst(new MockPropertySource()
.withProperty("my.property",
"factory.makeVal(1234)"));
psc.setPropertySources(sources);
return psc;
}
}
}