Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way to disable nested resolution of property placeholders [SPR-9931] #14564

Closed
spring-projects-issues opened this issue Oct 30, 2012 · 7 comments
Assignees
Labels
status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 30, 2012

Mickaël LEDUQUE opened SPR-9931 and commented

There should be a way to use <context:property-placeholder /> to bind a value without trying to evaluate nested values.

For example, I'd like to bind a value that contains a MessageFormat pattern like this one:

my.property={0}#{1}

(very simple case that shows the problem)

This # is a separator between the first argument {0} and the second one, {1}.
Of course, #{1} have no value in my context.

Then, I do :

<context:property-placeholder location="..." />
<bean id="myBean" class="my.class">
    <property name="myProp" value="${my.property}" />
</bean>

I need the property evaluation to not to try to be smart and just replace ${my.property} with it's value.

Instead it blows up, replacing #{1} by its value "".


Affects: 3.1.2

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

If it's #{...}, then it's SpEL expression parsing kicking in here. Phil, could you take a look here at various options for disabling SpEL expression parsing during property placeholder replacement? One option could be allowing the user to customize the "#{" expression prefix in the same way we do with customizing "${" and "}" for placeholder identification. I'm not sure at glance, however, whether the SpelExpressionParser and friends allow for this, though.

@spring-projects-issues
Copy link
Collaborator Author

Mickaël LEDUQUE commented

I don't really expect a solution or a fix so early, of course, but if I could have a workaround of an idea of where the problem really lies, that would greatly help.

@spring-projects-issues
Copy link
Collaborator Author

Phil Webb commented

Hi Mickaël,

Would it be possible for you to submit a pull request containing a simple sample application that replicates the problem. Instructions for this are available on GitHub.

Taking a quick look though the Spring codebase I wonder if you might be able to work around the problem by using a custom StandardBeanExpressionResolver bean. This bean has a setExpressionPrefix property that you could change to something that does not clash. It looks like StandardBeanExpressionResolvers are currently automatically registered (see the AbstractApplicationContext.prepareBeanFactory class). You can probably register your own variant by writing a BeanFactoryPostProcessor bean that calls beanFactory.setBeanExpressionResolver in the postProcessBeanFactory method.

The sample app would certainly help me confirm the above.

Cheers,
Phil.

@spring-projects-issues
Copy link
Collaborator Author

Mickaël LEDUQUE commented

I will make a pull request as soon as I'm not behind a stupid corporate gateway. It's mostly ready (nothing really hard here) but there are some constraints outside my power.

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

pull request submitted: spring-attic/spring-framework-issues#39

Thanks, Mickaël.

@spring-projects-issues
Copy link
Collaborator Author

Phil Webb commented

Hi Mickaël,

Thanks for the pull request. I would like to find a better solution but for now you can use the following work-around to change the SpEL prefix to something other than '#{' (in this case '#$#{'). Just register this class as a bean in you ApplicationContext.

public class ExpressionResolverFactoryPostProcessor implements BeanFactoryPostProcessor {
	
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
			throws BeansException {
		StandardBeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
		expressionResolver.setExpressionPrefix("#$#{");
		beanFactory.setBeanExpressionResolver(expressionResolver);
	}
}

Hope it helps.

Cheers,
Phil.

@spring-projects-issues
Copy link
Collaborator Author

Mickaël LEDUQUE commented

OK, thanks, that seems to work.
I'll use it, unless I discover that I can't globally change the prefix (but I think that'll work for me).

@spring-projects-issues spring-projects-issues added status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement labels Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants