Is there any way to reference grailsApplication from either resources.xml or a different xml file that is imported by resources.groovy?
For example, I am wiring up some beans in foo.xml that will be imported in resources.groovy. I would like to pull in some values from the external config, so it would be nice if I could do something like:
<bean id=fooBean class="com.beans.foo.FooBean">
<property name="exVar" value="${grailsApplication.config.some.path.to.ext.variable}"
</bean>
I've done this quite a bit in resources.groovy, so was wondering if there were a way to get at this object from xml. Thanks!
Looking at this related question you can use:
<bean id=fooBean class="com.beans.foo.FooBean">
<property name="exVar" value="${some.path.to.ext.variable}"
</bean>
Related
I have next applicationContext.xml file on the root of classpath:
<context:annotation-config />
<context:property-placeholder location="classpath:props/datasource.properties" />
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:url="${jdbc.url}"
p:driverClassName="${jdbc.driverclass}"
p:validationQuery="SELECT sysdate FROM dual" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="datasource"
p:mapperLocations="classpath:mappers/*-mapper.xml" />
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="datasource" />
<bean id="mappeScannerConfigurere" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:sqlSessionFactory-ref="sqlSessionFactory"
p:basePackage="com.mypackage" />
props/datasource.properties also exists on the root of classpath with such content:
jdbc.url=myjdbcurl
jdbc.driverclass=myClass
jdbc.username=myUserName
jdbc.password=myPassword
I have a spring managed test where I declare to use previously mentioned applicationContext.xml via next annotations:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:applicationContext.xml"})
When I invoke test method i get next error from spring:
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
As I understand sping didn't resolve reference to jdbc.driverclass.
What have I done wrong?
PS: I'm using spring 3.2.3.RELEASE
**
EDIT
**
Perhaps the problem may be in MapperScannerConfigurer. It is a BeanDefinitionRegistryPostProcessor and as Javadoc says:
Extension to the standard BeanFactoryPostProcessor SPI,
allowing for the registration of further bean definitions
before regular BeanFactoryPostProcessor detection kicks in
So MapperScannerConfigurer instantiates datasource object via sqlSessionFactory with BeanFacoryPostProcessor(which is responsible for <context:property-placeholder/>) have not been utilized.
So my question transforms to how to reorder BeanFacoryPostProcessor from <context:property-placeholder/> and BeanDefinitionRegistryPostProcessor(MapperScannerConfigurer)?
Resolved
After a couple hours of investigation I found the solution:
As I said earlier MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor which fires before BeanFactoryPostProcessor which is responsible for <context:property-placeholder/>. So, during the creation of MapperScannerConfigurer references to external properties will not be resolved. In this case we have to defer the creation of datasource to the time after BeanFactoryPostProcessorhave been applied. We can do that in several ways:
remove p:sqlSessionFactory-ref="sqlSessionFactory" from MapperScannerConfigurer. In this case datasource object will not be created before MapperScannerConfigurer, but after BeanFactoryPostProcessor which is responsible for <context:property-placeholder/>. If you have more than one sqlSessionFactory in applicationContext, than can be some troubles
In versions of mybatis-spring module higher than 1.0.2 there is a possibility to set sqlSessionFactoryBeanName instead of sqlSessionFactory. It helps to resolve PropertyPlaceHolder issue with BeanFactoryPostProcessor. It is a recommended way to solve this issue described in mybatis-spring doc
I was having the same issue and came across this post but I was unable to resolve it the same way maks did. What ended up working for me was to set the ignoreUnresolvablePlaceholders property value to true.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:database.properties</value>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
I am using Spring 3.2.3.RELEASE as well. I realize this post is over 4 months old but I figured someone might find it useful.
Short form: What is the proper way to load an implementation of: BeanDefinitionRegistryPostProcessor?
Expanded form: Is there a way to load BeanDefinitionRegistryPostProcessor before any beans have been created. If you look at the javadoc:
Extension to the standard {#link BeanFactoryPostProcessor} SPI, allowing for
the registration of further bean definitions before regular
BeanFactoryPostProcessor detection kicks in.
So it's meant to be loaded when bean definitions have been created but before any beans have been created. If we just create it as a regular bean in the application xml then it defeats the purpose of having this bean in the first place.
Why is autowiring required? What is the explanation for the concept of autowiring?
#autowired annotation in Spring Framework.
Autowiring is not required, just convenient.
It means that if you have a property that requires an InterfaceA and a single bean has been declared in Spring that is of type InterfaceA, instead of using XML to manually "wire up" the relationship (setting a bean reference as a property of another), you can let Spring do the wiring for you.
This is a common question for the beginners. As the beans are injected using DI (setter injections, constructor injections), why do we need auto-wiring? Auto-wiring also doing the same thing, right?
The answer is, it saves you from writing more code.
If using an XML file, using autowire attribute saves you from writing the wiring code in the bean definition.
Please look at code below.
Configuration code without Auto-wiring:
<bean id="employee" class="com.Employee">
<property name="name" value="Dexter"></property>
</bean>
<bean id="employeeService" class="com.EmployeeService">
<property name="employee" ref="employee"></property>
</bean>
Configuration code with Auto-wiring:
<bean id="employee" class="com.Employee">
<property name="name" value="Dexter"></property>
</bean>
<bean id="employeeService" class="com.EmployeeService" autowire="byName" />
Note that we did not have to write anything to refer property of EmployeeService, i.e., Employee. But still it was injected. Autowiring makes the container to search the bean configurations and do the collaboration among beans, without the developer specifically mentioning these.
If we use annotation, even we don’t have to write anything in XML files, including this autoware="byName", etc. Simply #Autowired on bean's setter/field/constructor is sufficient.
I want to load multiple properties files using <util:properties> tag in a spring 3 application.
I searched on the blogs, but cannot get the correct path to do this.
Hopefully somebody give me the answer to overcome this problem.
Actually <util:properties> is just convenient tag for org.springframework.beans.factory.config.PropertiesFactoryBean. And PropertiesFactoryBean does support multiple locations.
So it is possible to create bean with Properties this way:
<bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:myprops-common.properties</value>
<value>classpath:myprops-override.properties</value>
<value>classpath:some-more-props-here.properties</value>
</list>
</property>
</bean>
My solution
<context:property-placeholder location="classpath*:*.properties,file:/some/other/path/*.properties" />
util:properties seems to support only 1 properties file (reference). You might want to use the configuration suggested by #peperg.
I am new to spring (3.1) and totally stumped by this problem.
I am trying to access a property value "schdestination" using a PropertyPlaceholderConfigurer that is defined in two property files (one overriding the other).
I want to use #Value to set a field in a class and i just can't find a way to do it without using another bean. Here is my spring XML snippet
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/abc.properties</value>
<value>/WEB-INF/loc.abc.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>
Any clues please?
#Value("${schdestination}")
private String destination;
should work.
The class that contains the #Value needs to be annotated with #Component and you need to have <context:component-scan/> in your applicationContext.xml.
Are you using it in your web app? That was my case. I was loading property files from application context and somehow they were not visible in the web app package - controllers to be precise. I had to re-declare them in servlet-context.xml, then they are visible and work just fine. I am really hoping somebody might shed some light what could be going on, or whether it is truly an issue to be fixed in Spring.
is it possible to define in a spring context file, and one or more properties that
can be accessed in <bean> elements.
The example below illustrates best what I need - I want to define the property FOO once and then reference it multiple times in my various <bean> definitions:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<properties>
<property name="FOO" value="BAR">
</properties>
<bean name="TEST" class="mytest">
<property name="MYFOO" value="${FOO}"/>
</bean>
<bean name="TEST1" class="mytest1">
<property name="MYFOO" value="${FOO}"/>
</bean>
</beans>
Any input would be much appreciated.
Thanks, Kevin.
You can do this using the snappily-named PropertyPlaceHolderConfigurer. See here for the example in the spring docs. You don't define the property values themselves in the spring beans file, you externalise them in a .properties file.
You could, I suspect, use PropertyPlaceHolderConfigurer or one of its siblings to inject a Properties object defined inside your Spring file, but that would be a rather more verbose solution.
If you only need to define them in your xml file and never change them (like you would change a configuration option, say a port or an ip), you can create a bean of class String with the given property and then write . Creating a bean of class String isn't the most straight forward thing, but it's doable.
If you want something more complicated (say you want a configuration file residing outside the jar where your xml with the bean definition is), you can look at the PropertyPlaceholderConfigurer class.
Just found a way to do this all in the spring XML file with no external properties file needed (though you can supplement with one if desired)
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<util:properties>
<prop key="foo1">bar1</prop>
<prop key="foo2">bar2</prop>
</util:properties>
</property>
</bean>
then you reference them just like normal as ${foo1} where needed