Spring PropertiesFactoryBean that automatically exposes a PropertyPlaceholderConfigurer's property - spring

Ideally I'd like to do this from code:
#Value("#{aPropertiesFactoryBean.aProperty}")
private String aProperty;
Based on a spring configuration where I set up a PropertyPlaceholderConfigurer and a PropertiesFactoryBean, and just pass the configurer bean as a ref to the bean, and everything that the configurer generates is exposed as a property of the factory bean.
There is a hack to just redefine every property from the Configurer like:
<bean id="aPropertiesFactoryBean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="properties">
<props>
<prop key="aProperty">${aProperty}</prop>
</props>
</property>
</bean>
And then every time you add a property to the Configurer, you have to re-expose it with the FactoryBean. And the punchline is, I want all the management features of the configurer, and also be able to reference the same batch of properties from both the spring xml files, and #Value annotations.
So the two questions:
Is there something like this out of the box?
It looks like it would be simple to override PropertiesFactoryBean and give it a property for the PlaceholderConfigurer, but the code to actually access the properties would have to involve unwelding the hood through reflection and digging into Spring's internal PropertiesLoaderSupport class. Is there a less hacky way to do this?
Note, I'm not looking for something that can just quickly get me on my way, the above hack with PropertiesFactoryBean suffices for now. I'm looking to either find or make a reusable component that I can use to easily manage injectable properties for projects down the road.

I was just thinking about this backwards. This config does exactly what I want, being able to have properties defined in the xml config, overridable from a properties file, and available as both placeholder properties and injectable values.
<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-3.0.xsd">
<!--
One-stop shopping for properties here.
Available as injected values and elsewhere in the spring config.
-->
<bean id="injectableProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="properties">
<props>
<prop key="prop1">value1</prop>
<prop key="prop2">value2</prop>
</props>
</property>
<!-- Allow foo.conf to override default properties -->
<property name="location" value="file:/etc/foo/foo.conf" />
</bean>
<!-- Expose the properties so other parts of the spring config can use them -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="properties" ref="injectableProperties"/>
</bean>
</beans>

Maybe I'm misunderstanding the situation, but you can inject properties without having to define a PropertiesFactoryBean by using the syntax:
#Value("${my.property}") String myProperty;

Related

Why is MultiActionController deprecated in Spring 4.3?

In most cases, I'm able to replace MultiActionController with an annotated controller just fine. But I have a use-case where I need to map different URLs to DIFFERENT instances of the same controller class, each wired with a different implementation of the same interface. (It's for various find-as-you-type APIs.) I've been using SimpleUrlHandlerMapping for this. Is there any way to do this with an annotated controller? Or do I now have to make separate controller classes for each API? Here's my config with only two MultiActionControllers shown, although I have more:
<bean name="regionAutocompleteController" class="...ajax.autocomplete.AutocompleteController" autowire="byName">
<property name="finder" ref="regionFinder"/>
</bean>
<bean name="blockAutocompleteController" class="...ajax.autocomplete.AutocompleteController" autowire="byName">
<property name="finder" ref="blockFinder"/>
</bean>
<bean id="atlasAjaxControllerMappings"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="4" />
<property name="mappings">
<props>
<prop key="/findBlock/*">blockAutocompleteController</prop>
<prop key="/findRegion/*">regionAutocompleteController</prop>
</props>
</property>
</bean>

hibernate.search.default.directory_provider in spring beans rather than persistence.xml

I am in a rather nasty situation. We use compass for Hibernate search integration with Lucene and have implemented database directory search (using JdbcDirectory) instead of FSDirectoryProvider, RAMDirectoryProvider etc.
The problem is that the directory provider is passed as a property inside the META-INF/persistence.xml like the one below:
<property name="hibernate.search.default.directory_provider" value="uk.company.package.JdbcDirectoryProvider" />
We need to pass the database details to the the JdbcDirectoryProvider as JdbcDirectory requires a datasource to be passed.
We are constructing the datasource (for the directory provider) in an unconventional way using a property file (in the class path) with the database and index details.
If we have uk.company.JdbcDirectoryProvider configured as a spring bean, we can inject the datasource. This works well with Tomcat but not with OAS or Weblogic as still as we are passing the directory_provider in the persistence.xml. Probably becasue the datasource is initialized by the spring (becasue of the way classloaders work in these app servers).
My question is how can we configure the hibernate.search.default.directory_provider directly inside aSpring bean instead of the persistence.xml?
The closest place is:
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
But it only takes three properties:
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
Solution
You could pass the hibernate properties in spring bean as jpaProperties
<property name="jpaProperties">
<props>
<prop key="hibernate.search.default.directory_provider">
uk.company.package.JdbcDirectoryProvider
</prop>
</props>
</property>
I found the solution.
You could pass the hibernate properties in spring bean as jpaProperties
<property name="jpaProperties">
<props>
<prop key="hibernate.search.default.directory_provider">
uk.company.package.JdbcDirectoryProvider
</prop>
</props>
</property>

Loading properties from a file AND system properties using Spring

Searched through some other posts but could not find exactly what I needed, but I would guess this is an easy question..
So I have a property file called myprops.properties
myprops.localProp1=localProp1
myprops.localProp2=localProp2
myprops.systemProp=${systemPropertyName}
Basically, in this property file I want to use the values as is for localProp1 and locapProp2 but for systemProp, I would like to load the system property. Let's assume that the system property is always set.
My spring config xml looks like this...
<bean id="myprops" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<qualifer value="myprops" />
<property name="singleton" value="true"/>
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list><value>classpath:myprops.properties</value></list>
</property>
</bean>
I use the qualifier have this bean autowired and use the qualifier string "myprops" to access it in another class. All the expected values are there except the myprops.systemProp, it still = ${systemPropertyName}.
How would I get this property to be resolved with the actual system property?
I tried the following in my spring config:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="myprops" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
This didn't seem to help..
Any ideas? I'm hoping this is an easy one and I am just misunderstanding a common concept in property configuration.
Note: I had to manually type all the code couldn't copy/paste so please excuse typos.
Thanks.

Define local property for list of bean refs in Spring

Spring 3.x
I have a growing list of filters in a filter-chain and am looking for a way to reduce the verbosity of these declarations in my context file. eg, using the example from the spring docs
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**" filters="
securityContextPersistenceFilterWithASCFalse,
basicAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
Imagine we have many patterns that all require the same filter chain, I want to be able to define a string local to this context like "
securityContextPersistenceFilterWithASCFalse,
basicAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" and use it in the context like so
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/foo/**" filters="${defaultFilterChain}" />
<sec:filter-chain pattern="/bar/**" filters="${defaultFilterChain}" />
...
</sec:filter-chain-map>
</bean>
Properties are not of use here, as they will be treated as a String, not as a list that can be used as bean refs.
Replacing property placeholders like that is done using PropertyPlaceholderConfigurer which can take properties from external resources, but it can also take properties directly and it can use both external and directly configured at the same time. External properties will override directly configured properties, making directly configured properties useful as defaults (this behavior can be switched off making it the other way around).
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<props>
<prop key="defaultFilterChain">securityContextPersistenceFilterWithASCFalse, basicAuthenticationFilter, exceptionTranslationFilter, filterSecurityInterceptor</prop>
</props>
</property>
</bean>
This works. http://forum.springsource.org/showthread.php?87497-PropertyOverrideConfigurer-for-bean-references

Spring MVC from 2.5 to 3.0

We are migrating our web application from Spring 2.5 to Spring 3.0.5. Looks like all the Controller classes (the classes in org.springframework.web.servlet.mvc package: BaseCommandController, AbstractCommandController, SimpleFormController, etc) have been deprecated. We used those classes heavily in our application. These classes have been replaced by #Controller annotation instead.
I have a few questions regarding Spring 3.0.x Controller configuration...
We used the following XML to create a Controller bean in Spring 2.5. If <context:component-scan> is used instead to create the Controller beans, then how do I wire-in the dependencies? If possible I would like to avoid Auto-Wiring.
<bean id="photosetViewController" class="com.xyz.web.PhotosetViewController"
p:photosetManager-ref="photosetManager"
p:photoManager-ref="photoManager" />
We have created 3 Interceptors. We use SimpleUrlHandlerMapping to map these Interceptors to different request URLs and also to map URLs to Controllers. How do we achieve the same in Spring 3.0.x?
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true" />
<property name="interceptors">
<list>
<ref bean="httpRedirectInterceptor"/>
<ref bean="loginInterceptor"/>
</list>
</property>
<property name="mappings">
<value>
/abc.html=abcLookupController
/photoupload.html=photoUploadController
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true" />
<property name="interceptors">
<list>
<ref bean="httpRedirectInterceptor"/>
<ref bean="loginInterceptor"/>
<ref bean="userMenuInterceptor" />
</list>
</property>
<property name="mappings">
<value>
/index.html=homepageController
/success.html=simpleController
</value>
</property>
</bean>
In case of SimpleFormControllers we used different methods like initBinder, referenceData, formBackingObject. We also used command objects and validation classes. How do we achieve the same in Spring 3.0.x?
<bean id="photosetAddController" class="com.xyz.web.PhotosetAddController"
p:photosetManager-ref="photosetManager"
p:photosetTypeManager-ref="photosetTypeManager"
p:stateManager-ref="stateManager" >
<property name="validator">
<bean class="com.xyz.form.PhotosetAddValidator" />
</property>
<property name="formView" value="photosetadd" />
<property name="successView" value="redirect:/photoset" />
</bean>
Any pointers are greatly appreciated.
As skaffman noted - your code will work fine without any modifications. I'll answer your questions in short:
You can use #Resource(name="beanName") for name-based injection. But autowiring is also a good option. Either #Autowired, or #javax.inject.Inject. Note that you can use #Qualifier("name") to differentiate between beans with the same interface/base class. You can even use the javax.inject qualifiers (read about all these in the docs)
interceptor mappings can stay the same
There is #InitBinder, which denotes the initBinder method. I can't tell about the other.

Resources