How to Inject a Property Value into a Spring Bean Which Was Configured Using Annotations

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 your foo 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



Leave a reply



Submit