当前位置: 首页 > 知识库问答 >
问题:

在SpEL中使用应用程序范围的属性(以编程方式)

高明辉
2023-03-14
application.name=AppTest
company.name=ACME Inc.
/path/to/#{application.name}/#{company.name}

#或$对我来说无关紧要

通常在Spring中,您可以将属性注入bean,我已经成功了。但是现在我希望用户输入一个模板字符串,可以使用应用程序上下文中的所有属性进行翻译。目前我不需要访问bean属性,但将来我可能需要。以上是定义文件夹路径时最常见场景的简化变体。运行时参数(例如,一天中的时间)增加的复杂性很小,但我问的问题是一步一步地工作。

因此,我试图在JUnit的帮助下,通过玩Spring表达式来理解它们。我编写了以下代码,但无法使其工作

final HashMap<String, Object> propertySource = new HashMap<String, Object>();
private final String FOLDER_PATTERN = "#tmp/appTest/#{company}_#{appname}/q1"; //#tmp is only token being replaced "hardcoded", not passed to Spring

@Before
public void setUp() throws Exception
{

    propertySource.put("appname", APPNAME);
    propertySource.put("company", COMPANY);
    applicationContext.getEnvironment()
                      .getPropertySources()
                      .addLast(new MapPropertySource("test", propertySource));

}

@Test
public void playWithExpression()
{
    ExpressionParser expParser = new SpelExpressionParser();
    StandardEvaluationContext stdEvaluationContext = new StandardEvaluationContext();
    stdEvaluationContext.setBeanResolver(new BeanFactoryResolver(applicationContext.getBeanFactory()));
    // stdEvaluationContext.setVariables(propertySource);

    final TemplateParserContext templateParserContext = new TemplateParserContext();

    String folderPattern = FOLDER_PATTERN.replace("#tmp", SYSTEM_TEMP_DIR);

    String realPath = expParser.parseExpression(folderPattern, templateParserContext)
                               .getValue(stdEvaluationContext, String.class);

    String calculatedPath = folderPattern.replace("#{company}", COMPANY)
                                         .replace("#{appname}", APPNAME);

    assertEquals(calculatedPath, realPath);

}
    null
org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'company' cannot be found on null
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:220)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:299)
    at org.springframework.expression.common.CompositeStringExpression.getValue(CompositeStringExpression.java:89)
    at org.springframework.expression.common.CompositeStringExpression.getValue(CompositeStringExpression.java:136)
    at it.phoenix.web.data.managers.test.FoldersManagerTemplateTests.playWithExpression(FoldersManagerTemplateTests.java:80)

如何解析表达式中AppContext的PropertySource的属性?

共有1个答案

乌和畅
2023-03-14

也许有一个更优雅的解决方案,但是

private final String FOLDER_PATTERN = "#tmp/appTest/#{environment.getProperty('company')}"
        + "_#{environment.getProperty('appname')}/q1";  // #tmp is only token being replaced
                                                        // "hardcoded", not passed to Spring

    String realPath = expParser.parseExpression(folderPattern, templateParserContext)
            .getValue(stdEvaluationContext, applicationContext, String.class);

工作(即使用应用程序上下文作为计算中的根对象)。

private final String FOLDER_PATTERN = "#tmp/appTest/#{getProperty('company')}"
        + "_#{getProperty('appname')}/q1";  // #tmp is only token being replaced
                                            // "hardcoded", not passed to Spring
    String realPath = expParser.parseExpression(folderPattern, templateParserContext)
            .getValue(stdEvaluationContext, applicationContext.getEnvironment(), String.class);
 类似资料:
  • 使用运行相同的表达式可以正常工作。

  • 我一直在探索构建我的ColdFusion应用程序的不同方法,我正在寻找一些关于提供应用范围UDF的最佳方式的意见。 对于我的每一个应用程序,我通常都会使用一些不属于任何特定对象的额外功能。主要是数据操作。我希望这些功能在我的整个应用程序中都可用,既可以在CFM模板中使用,也可以在应用程序实例化的CFC中使用。 在我看来,有各种各样的方法来实现这一点,但它们都有自己的局限性: > 创建一个基本的Ut

  • 我正在尝试使用我自己的应用程序实现或扩展的ResourceConfig或PackageResourceConfig来配置我的Jersey应用程序。因此,我的第一次尝试是将现有的web.xml(实际上,由于开发的库性质,我使用的是web-fragment.xml)配置移植到MyApplication实现。 当我使用第二个版本时,我会收到以下信息 正如您所看到的,是第一个注册的类,但由于它不是公共的,

  • 我在src/main/resources下创建了2个文件: 应用程序。属性 第一个具有从env变量中获取值的属性,而后者具有固定值。 根据这里的具体情况,我以这样的方式推出了Spring靴: 然而,不会产生任何影响,并且应用程序是局部的。属性似乎被忽略。 有什么提示吗?

  • 问题内容: 如何确保从hibernate.cfg.xml加载所有属性,然后以编程方式添加其他属性?我看到了以下代码片段,但它看起来像是全新的配置,而不是现有配置的补充。 问题答案: 您显示的代码段是您所需要的。只需使用您现有的配置,而不是创建一个新的配置即可。 如果不是您实例化配置(例如,spring),则需要扩展创建它的类。

  • 问题内容: 我们使用下面的代码从属性文件中注入具有属性的Spring bean。 有没有一种方法可以通过编程方式访问属性?我试图做一些没有依赖注入的代码。所以我只想要一些这样的代码: 问题答案: 怎么样?