Is there a way to @Autowire a bean that requires constructor arguments?

Viewed 208863

I'm using Spring 3.0.5 and am using @Autowire annotation for my class members as much as possible. One of the beans that I need to autowire requires arguments to its constructor. I've looked through the Spring docs, but cannot seem to find any reference to how to annotate constructor arguments.

In XML, I can use as part of the bean definition. Is there a similar mechanism for @Autowire annotation?

Ex:

@Component
public class MyConstructorClass{

  String var;
  public MyConstructorClass( String constrArg ){
    this.var = var;
  }
...
}


@Service
public class MyBeanService{
  @Autowired
  MyConstructorClass myConstructorClass;

  ....
}

In this example, how do I specify the value of "constrArg" in MyBeanService with the @Autowire annotation? Is there any way to do this?

Thanks,

Eric

9 Answers

Another alternative, if you already have an instance of the object created and you want to add it as an @autowired dependency to initialize all the internal @autowired variables, could be the following:

@Autowired 
private AutowireCapableBeanFactory autowireCapableBeanFactory;

public void doStuff() {
   YourObject obj = new YourObject("Value X", "etc");
   autowireCapableBeanFactory.autowireBean(obj);
}

I like Zakaria's answer, but if you're in a project where your team doesn't want to use that approach, and you're stuck trying to construct something with a String, integer, float, or primative type from a property file into the constructor, then you can use Spring's @Value annotation on the parameter in the constructor.

For example, I had an issue where I was trying to pull a string property into my constructor for a class annotated with @Service. My approach works for @Service, but I think this approach should work with any spring java class, if it has an annotation (such as @Service, @Component, etc.) which indicate that Spring will be the one constructing instances of the class.

Let's say in some yaml file (or whatever configuration you're using), you have something like this:

some:
    custom:
        envProperty: "property-for-dev-environment"

and you've got a constructor:

@Service // I think this should work for @Component, or any annotation saying Spring is the one calling the constructor.
class MyClass {
...
    MyClass(String property){
    ...
    }
...
}

This won't run as Spring won't be able to find the string envProperty. So, this is one way you can get that value:

class MyDynamoTable
import org.springframework.beans.factory.annotation.Value;
...
    MyDynamoTable(@Value("${some.custom.envProperty}) String property){
    ...
    }
...

In the above constructor, Spring will call the class and know to use the String "property-for-dev-environment" pulled from my yaml configuration when calling it.

NOTE: this I believe @Value annotation is for strings, intergers, and I believe primative types. If you're trying to pass custom classes (beans), then approaches in answers defined above work.

Related