How can I inject a property value into a Spring Bean which was configured using annotations?
You can do this in Spring 3 using EL support. Example:
@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }
@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }
systemProperties
is an implicit object and strategyBean
is a bean name.
One more example, which works when you want to grab a property from a Properties
object. It also shows that you can apply @Value
to fields:
@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;
Here is a blog post I wrote about this for a little more info.
Spring: How to inject a property value into the bean via XML?
Try this:
<bean id="myBean" class="com.test.MyBean">
<property name="value" value="${app.settings.value}"/>
</bean>
The syntax is the same as for java config - prefixed with the $
sign.
Inject property to spring bean using annotation
Ok, got it!
I'm using a spring MVC project, which means I have a separated context for my web layer (the controllers). The "Configuration" bean which hods the properties using the @Value annotation is injected to a controller. My property-placeholder is defined within my root-context hence it cannot be seen from my controller. To resolve the issue I simply added the property-placeholder definition to my DispatcherServlet context and it works like a charm :)
property value injection into spring beans
Basically propertyValue
is null because Spring injects value after bean's creation.
So when you do:
@Bean
public IWebserviceEndpoint webserviceEndpoint() {
return new WebserviceEndpoint();
}
Spring creates a new instance with propertyValue=null
.
You can initialize your instance attribue with @ConfigurationProperties
@Bean
@ConfigurationProperties(prefix=...)
public IWebserviceEndpoint webserviceEndpoint() {
return new WebserviceEndpoint();
}
Note that propertyValue
should have a setter.
You have several ways to solve this problem, usually it's good to centralize properties in one utils class.
@Component
public class Configs {
@Value("${propery}"
String property;
String getProperty(){
return property;
}
}
And then:
@Bean
@ConfigurationProperties(prefix=...)
public IWebserviceEndpoint webserviceEndpoint() {
WebserviceEndpoint we = new WebserviceEndpoint();
we.setProperty(configs.getProperty())
return we;
}
Again there are many many different ways to solve this problem
Injecting Properties using Spring & annotation @Value
For your solution to work you would also need to make foo a Spring managed bean; because otherwise how would Spring know that it has to deal with any of your annotations on your class?
- You can either specify it in your appcontext xml as a bean with
..class="foo"
- Or use
component-scan
and specify a base package which contains yourfoo
class.
Since I'm not entirely sure this is exactly what you want (don't you want a .properties file to be parsed by Spring and have it's key-value pairs available instead of a Properties
object?), I'm suggesting you another solution: Using the util
namespace
<util:properties id="props" location="classpath:com/foo/bar/props.properties"/>
And reference the values inside your beans (also, have to be Spring managed):
@Value("#{props.foo}")
public void setFoo(String foo) {
this.foo = foo;
}
EDIT:
just realized that you are importing org.springframework.context.ApplicationContext
in your class which is probably unnecessary. I strongly encourage you to read Spring reference at least the first few chapters, because a) it's a great read b) you will find it much easier to understand Spring if the basics are clear.
Spring inject property values from a bean into another bean
Try using the expression langugage:
@Value(#{anotherBean.location})
private String location
@Value(#{anotherBean.enabled})
private boolean enabled
Update
Alternatively you can assign that in the post construct:
@Autowired
private AnotherBean anotherBean;
@PostConstruct
public void init(){
location = anotherBean.getLocation();
enabled = anotherBean.isEnabled();
}
Update 2
The last thing that comes to my mind that could work out of the box is changing the scope of the first bean to prototype instead of singleton:
@Scope("prototype")
Now everytime this bean would used (getBean on spring context for example) a new instance would be created.. and everytime fresh data from anotherBean wouuld be injected.
But this is specific so you would have to think whether this scenario fits your application.
Related Topics
Java Generating Non-Repeating Random Numbers
How to Store Date/Time and Timestamps in Utc Time Zone with JPA and Hibernate
Difference Between Paint, Paintcomponent and Paintcomponents in Swing
How to Access a Value Defined in the Application.Properties File in Spring Boot
Does the Jvm Prevent Tail Call Optimizations
Why One Should Prefer Using CSS Over Xpath in Ie
Convert a JSON String to a Hashmap
Embed Java into a C++ Application
How to Use Vectordrawables in Android API Lower Than 21
Java Simpledateformat("Yyyy-Mm-Dd'T'Hh:Mm:Ss'Z'") Gives Timezone as Ist
In Java, How to Write a String Literal Without Having to Escape Quotes
In Java, How to Parse Xml as a String Instead of a File
Java - Class.Getresource Returns Null
How to Add a Filter Class in Spring Boot
Java, Calculate the Number of Days Between Two Dates