Syntax for specifying spring xml files in ClassPathXmlApplicationContext - java

I am trying to find out the syntax for specifying the spring's XML file in the constructor of ClassPathXmlApplicationContext. By syntax I don't mean the method signature but the actual string
For example the following three work.
ApplicationContext context = new ClassPathXmlApplicationContext("com/anshbansal/alarm/alarm.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alarm.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("alarm.xml");
I have googled and tried to go through the Spring 3.1.0 source code also. But I got stuck after doResolvePlaceholders method in org.springframework.core.env.AbstractPropertyResolver class of Spring. Specificaly I was not able to understand how placeholders are resolving to the path.
Can anyone share what is the syntax for the string to specify the xml file?
EDIT
I mean the syntax to specify path to spring xml file like in the constructor. I do not mean the syntax of the xml file itself.

Ok, I understand the question now :-). PropertyResolver is used only to put environment values (or property file values) into spring XML file, i.e.:
<context:property-placeholder location="file:///some/path/file.properties"/>
and then resolving them inside this spring xml, i.e.:
<bean id="mailInviteMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.from}"/>
<property name="subject" value="${mail.subject}"/>
</bean>
Putting spring XML in the classpath and naming in standard convention (i.e. beans.xml) is preferable. However, you may configure it putting a parameter to java invocation, i.e.
java -Dmy.parameter=/path/to/beans.xml ...
and then loading it manually:
Context context = new FileSystemXmlApplicationContext(System.getProperty("my.parameter"));

Related

Spring load command line arguments from xml application context

How can I use varargs from Spring application context xml?
java -jar my.jar --variable=value
application-context.xml
<bean id="fooClassInstance" class="my.package.FooClass">
<property name="myproperty" value="${variable}" />
</bean>
Try to use System properties:
java -Dvariable=value -jar my.jar
That either works out of the box or you need to tell the app context to look at system properties when it expands variables. It's been a while since I tried that.
A good starting point is PropertySourcesPlaceholderConfigurer.
When you do something like this in your Spring XML config
<bean id="fooClassInstance" class="my.package.FooClass">
<property name="myproperty" value="${variable}" />
</bean>
Spring uses PropertyPlaceholderConfigurer to search for those variables in System/enviroment variables and/or list of predefined properties files.
So the easiest way is to pass that value as a system or environment variable with -Dvariable=value.
If you want to pass those values as arguments into min you can still do hacks like
public static void main(String[] args) {
// parse arguments into key, value pairs
System.setProperty(<key>, <value>);
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(<your XML config file>);
// use Spring context to get beans
}

Spring putting dynamically generated values into placeholders

I am new to Spring. I now understand how to use placeholders to read values from a properties file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:properties.txt"/>
</bean>
<int-mqtt:outbound-channel-adapter id="mqtt-publish"
client-id="${clientID}"
client-factory="clientFactory"
auto-startup="true"
url="${url}"
default-qos="${qos}"
default-retained="${retain}"
default-topic="${topic}" />
Everything works fine with the code above... But... Is it possible for instance to replace the clientID by something generated at runtime (or from user input) instead of statically reading it from a properties file?
By runtime, do you mean dynamically for each message?
In that case, no, because the clientId is used while establishing the connection, which is done once (or when the connection to the server is lost).
If you mean to provide a dynamic value programmatically when the application context initializes, then, yes, the Spring Expression Language is the solution.
For example, #{myBean.myProperty} will call the getMyProperty() method on a bean myBean and #{myBean.someMethod()} will invoke someMethod().
Also see the dynamic-ftp sample, which uses placeholders at runtime by creating a new outbound adapter on demand using property placeholders, in a child application context.

Spring context:property-placeholder for a boolean value

I am working on an application where I have two classes both implementing a common interface. So in time of bean declaration, I am going to mark one of them primary in my app-context.xml file. I can achieve this by simply declaring the primary bean like this:
<bean id="oracleImpl" class="com.me.dao.OracleImpl" primary="true">
</bean>
Now I don't want to hard code which of the beans is going to be the primary bean, rather want to read the true/false value from a properties file. So I went like this:
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="oracleImpl" class="com.me.dao.OracleImpl" primary="${oracle.primary}">
</bean>
<bean id="pgsqlImpl" class="com.me.dao.PgsqlImpl" primary="${pgsql.primary}">
</bean>
The values of oracle.primary and pgsql.primary are defined in the file jdbc.properties along with other jdbc (non-boolean) properties.
But it doesn't work and says, "'${oracle.primary}' is not a valid value for 'boolean'"
I have a feeling it is something to do with the xsd validators. Browsing through this site and google gave me this much idea, but got no real solution. Can any body help?
This will not work.
As of 3.2.5.RELEASE only the following bean definition elemets support property placeholder:
parent name
bean class name
factory bean name
factory method name
scope
property values
indexed constructor arguments
generic constructor arguments
See the BeanDefinitionVisitor's visitBeanDefinition method for the details. This method is used by the PlaceholderConfigurerSupport.
I would recommend you to create a feature request in the spring issue management system.
PS: if you create an issue please add a comment to the issues url.

Property expansion with PropertiesFactoryBean

I wish to expose a Properties Spring bean whose values have been expanded via the typical property expansion mechanism. I'm using Spring 3.1. Let me digress.
Given the following properties file:
server.host=myhost.com
service.url=http://${server.host}/some/endpoint
And this portion of Spring XML config file:
<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:default.properties</value>
</list>
</property>
</bean>
<context:property-placeholder properties-ref="appProperties" />
I can write the following working code:
#Component
public class MyComponent {
#Autowired
#Qualifier("appProperties")
private Properties appProperties;
#Value("${service.url}")
private String serviceUrl;
// remainder omitted
}
The only problem is that if I obtain the service.url value from appProperties I get http://${server.host}/some/endpoint - ie the value is unexpanded. However, if I get the value of service.url from serviceUrl, the value has been expanded: http://myhost.com/some/endpoint.
Does anyone know of a good way to expose a Properties instance as a Spring bean whose values have been expanded?
Alternatively, if anyone can point me to a Spring bean (must be Spring 3.1) that will do the expansion for me, I'll accept this too! (Interestingly, if you manually pull the property values from the Environment or PropertySource you'll find that these too are unexpanded.)
Thanks,
Muel.
I'm pretty late to this, but it's been viewed enough times that i figured it warranted a quick response. What you're seeing is an artifact of how Spring handles property expansion. When the need for property expansion is found, only previously loaded sources are checked, not the currently loading property source. When the file loads, there are no previous sources, so ${server.host} does not expand. When you later reference ${server.url} via the #Value annotation, the property file source is loaded and can be searched as you expected. This is why the #Value annotation gets full expansion but the result queried from the property file does not.

How to get display-name from web.xml in a Spring IoC XML Configuration

To be exact, how can I get the value of the <display-name> tag under the <web-app> tag stored in an application's web.xml in a Spring application context configuration XML file.
Ideally I would like something like the following...
<bean><property value="${servletContext.servletContextName}/></bean>
It seem like ServletContext.getServletContextName() does what I want but I can't seem to figure out how to get a handle on that in the Spring application context file.
Ok, the answer is trivial in Spring 3.0.x. Per the documentation for ServletContextFactory
Deprecated. as of Spring 3.0, since "servletContext" is now available as a default bean in every WebApplicationContext
So I decided to try the following and it worked!
<bean><property value="#{servletContext.servletContextName}/></bean>
Since servletContext object is implicitly defined we can access it via Spring EL using the #{} syntax.
I don't think you can do this via the XML config.
You can autowire a bean to receive the ServletContext object (or implement ServletContextAware), and fetch it from that programmatically, but I don't think the XML expressions have any visibility of it.
Maybe try the Expression Language?
<bean>
<property value="#{T(javax.servlet.ServletContext).getServletContextName()}"/>
</bean>
I suspect that would print null if it works though, since there is no context yet.

Categories