Spring 3.0.5 doesn't evaluate #Value annotation from properties - spring

Trying to auto-wire properties to a bean in Spring 3.0.5.RELEASE, I'm using:
config.properties:
username=myusername
main-components.xml:
<context:property-placeholder location="classpath:config.properties" />
MyClass:
#Service
public class MyClass {
#Value("${username}")
private String username;
...
}
As a result, username gets set to literally "${username}", so the expression doesn't get parsed. My other auto-wired dependencies on this class get set, and Spring doesn't throw any exception. I also tried to add #Autowired but it didn't help.
If I parse properties to a separate bean and then use #Autowired + #Qualifier, it works:
<bean id="username" class="java.lang.String">
<constructor-arg value="${username}"/>
</bean>
Any ideas how to use just #Value? Maybe I need to include some Spring dependency that I haven't? Thank you

Found what the issue was. Copy/paste from comments:
Are you sure you have <context:property-placeholder> in the same application context as your MyClass bean (not in the parent context)? – axtavt
You're right. I moved <context:property-placeholder> from the context defined by the ContextLoaderListener to the servlet context. Now my values get parsed. Thanks a lot! - alex

Related

How to inject spring properties into wicket components?

I'm searching for a possibility to inject a property which is defined in a spring context (provided by a propertiesFactoryBean) into a wicket component. I know the way to inject beans into components by using the #SpringBean-Annotation, but whats the corresponding way for properties?
The way my property is defined:
<bean id="myPropertiesFactory" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="mySpringProperty">mySpringProperty</prop>
</property>
</bean>
Things I've tried. The way it works usually with self defined beans:
#Inject
#Value("${mySpringProperty}")
Using the name of the propertiesFactory to access the property value
#Inject
#Value("$myPropertiesFactory.properties.mySpringProperty")
Using the Value Annotation
#Value("#myPropertiesFactory['mySpringProperty']")
Using SpringBean
#SpringBean(name="myPropertiesFactory.mySpringProperty")
None of these solutions works. So to get mySpringProperty injected i use the workaround to create a bean of the type String which get's injected properly by wicket when i annotate the corresponding member of my component with SpringBean but i think there must be a better solution.
<bean id="mySpringPropertyBean" class="java.lang.String">
<constructor-arg type="java.lang.String" value="https://foobar.com" />
</bean>
Annotate
#SpringBean
private String mySpringPropertyBean;
#SpringBean only supports injection of spring beans. I suppose someone could implement a #SpringValue annotation that does what you want, but as far as I know noone ever did.
What I usually do is:
My wicket application class is a spring bean.
It has properties with #Value annotations - as the object is a spring bean, these are evaluated and set properly
I access the actual values by calling MyApplication.get().getXXX() or ((MyApplication)getApplication()).getXXX()
If the app grows and the number of attributes approach a limit, I refactor them into separate Settings or Config classes - each one a spring bean of it's own, accessible from the application class.
In your Wicket class use instead of #Value("${mySpringProperty}"):
#SpringBean
private PropertiesConfiguration propertiesConfiguration;
Create a new PropertiesConfiguration class:
#Component
public class PropertiesConfiguration {
#Value("${mySpringProperty}")
private String mySpringProperty;
//getters & setters
}
Use in your wicket class:
System.out.println("mySpringProperty=" + propertiesConfiguration.getMySpringProperty());

Spring inject bean is always singleton

We are using spring 3.2.
We defined a bean myAccountVO in spring.xml files and set the scope to prototype, but the spring creates this bean as singleton bean.
Here is the spring xml:
<bean name="myAccountVO1"
class="valueobject.AccountVO"
scope="prototype" >
<property name="accountNo" value="0105069413007" />
<property name="accountType" value="01" />
</bean>
The service class is:
#Service //I've tested the #Scope("prototype") but no luck
public class AccountSummary {
#Autowired //I also tested #Resource but same result
private AccountSummaryVO myAccountSummaryVO1;
AccountSummaryVO getAccount(){
return myAccountSummaryVO1
}
}
Later we use this service as:
#Autowired
AccountSummary accountSummary;
............
accountSummary.getAccount()
As far as I get the AccountSummary class, itself, is a singleton and will not be instantiated every time.
It seems are very basic usecase, but I don't know what am I missing.
I don't see where you are injecting myAccountVO1.
But I guess when you reveal the injected place that it's probably a member of a bean which itself is not in the scope prototype, e.g. #Service or #Controller. The service bean will be instantiated with a newly created myAccountVO1, but this instance stays there forever.
Change the scope of the containing bean. See 4.5.3 Singleton beans with prototype-bean dependencies.
This applies as well to the beans which have the service beans injected.

Reference an Annotated Spring Component in an XML Bean Definition

I am using an external library that requires that I configure it using an XML Bean definition; in the Bean definition I need to provide an external class with a Bean from my project. I am using spring annotations with component scanning.
How do I reference my annotated Bean within the XML Bean Definition?
Are there any alternatives to creating an XML Bean Definition?
Details: Spring 3.0.7
No matter how it got created (based on XML- or annotation- metadata), every bean ends up in the application context under a unique name.
If you've just annotated your class with #Component or derivatives, without stating any name, the default naming scheme will be applied and the bean name will be your class name with the first character lowercased: ClassName => "className".
With that in mind, if you need to inject that bean in an XML bean definition, you do it like with any other bean in your context:
<bean id="someBean" class="SomeClass">
<property name="someProp" ref="className"/><!-- to stick to the above example -->
</bean>
Since you're mixing annotations with XML, the application context will be able to locate the "className" bean properly.
The #Service annotation takes an optional String value which can be used to give the bean a name of your choosing. For example, if your custom bean looks like:
#Service("mySpecialName")
public class MyClass { ... }
Then your xml could have:
<bean class="com.someone.else.library.SomeClass">
<property name="someProp" ref="mySpecialName"/>
</bean>
Make sure add below code in your xml file
<context:component-scan base-package="" />
<context:annotation-config />

Spring injection bind toInstance

Is there a way to bind an injected object to a specific instance using Spring DI similar to Google Guice's
bind(MyClass.class).toInstance(myclassobject);
If the constructor or member variable is annotated with #Autowired, Spring will try to find a bean that matches the type of the Object. You can get similar functionality to the annotation using #Qualifier, for example:
bind(MyClass.class).annotatedWith(Names.named("main")).toInstance(myclassobject);
would become in Spring:
#Autowired #Qualifier("main") private MyClass myClassObject;
<bean name="myClassObject" class="example.MyClassImpl">
<qualifier value="main"/>
</bean>
See http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation for more.

How to Inject Spring ReloadableResourceBundleMessageSource

In order to programmatically refresh the resource bundle cache, I am using Spring's ReloadableResourceBundleMessageSource. I am having trouble injecting it into my bean where I want to invoke the clearCache() method.
I've had to resort to the following:
private ReloadableResourceBundleMessageSource messageSource;
#Autowired
public void setMessageSource(MessageSource messageSource) {
this.messageSource = (ReloadableResourceBundleMessageSource((DelegatingMessageSource)messageSource).getParentMessageSource();
}
This works, but there must be a better way. The message resource is defined as follows:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" >
<list>
<value>WEB-INF/content/Content</value>
</list>
</property>
</bean>
I don't understand why Spring is injecting a message source of type DelegatingMessageSource.
I don't think that autowiring by type will work in this case, as the autowire candidate will most likely be the ApplicationContext itself (see section 3.8.2 of the reference documentation). This leads to all those layers you have to dig through to get your original ReloadableResourceBundleMessageSource.
Try passing a reference to the messageSource bean via XML configuration instead. Annotating the property with #Qualifier('messageSource') should work as well.
You usually get the DelegatingMessageSource injected when Spring can't find "messageSource" defined. Are you sure you're defining it properly or that it's visible where necessary? I think the problem here is how the XML configuration has been setup.
I had a similar situation with Spring Web Flow and the form action stuff. In my XML configuration the "messageSource" wasn't visible and causing the DelegatingMessageSource to be injected. I placed the "messageSource" bean definition into the webflow configuration and then everything worked and I stopped getting the DelegationMessageSource object. However, this is an ugly fix since now I have "messageSource" defined in two places.
Anyway, this problem only started after I switched to Spring 2.5.6. I'm using Webflow 1. Once I have a chance I will try and update to Webflow 2 and see what happens. Maybe that will fix the issue.
have you tried to define the method as:
public void setMessageSource(ReloadableResourceBundleMessageSource messageSoure) {
this.messageSoure = messageSoure;
}
When you try to run it through messageSource in your controller, you get NOTHING, empty string. And if you look closely, you will find that you have a DelegatingMessageSource in your messageSource property, with an empty parent source, which means it is EMPTY, i.e. always returns blank and this exception occurs in controller
ReloadableResourceBundleMessageSource incompatible with org.springframework.context.support.DelegatingMessageSource
Read more..

Resources