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

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


You need the @Value annotation.

A common use case is to assign default field values using"#{systemProperties.myProp}" style expressions.

public class SimpleMovieLister {  private MovieFinder movieFinder;  private String defaultLocale;  @Autowired  public void configure(MovieFinder movieFinder,                         @Value("#{ systemProperties['user.region'] }") String defaultLocale) {      this.movieFinder = movieFinder;      this.defaultLocale = defaultLocale;  }  // ...}

See: Expression Language > Annotation Configuration


To be more clear: in your scenario, you'd wire two classes, MybeanService and MyConstructorClass, something like this:

@Componentpublic class MyBeanService implements BeanService{    @Autowired    public MybeanService(MyConstructorClass foo){        // do something with foo    }}@Componentpublic class MyConstructorClass{    public MyConstructorClass(@Value("#{some expression here}") String value){         // do something with value    }}

Update: if you need several different instances of MyConstructorClass with different values, you should use Qualifier annotations


Well, from time to time I run into the same question. As far as I know, one cannot do that when one wants to add dynamic parameters to the constructor. However, the factory pattern may help.

public interface MyBean {    // here be my fancy stuff}public interface MyBeanFactory {    public MyBean getMyBean(/* bean parameters */);}@Componentpublic class MyBeanFactoryImpl implements MyBeanFactory {    @Autowired    WhateverIWantToInject somethingInjected;    public MyBean getMyBean(/* params */) {        return new MyBeanImpl(/* params */);    }    private class MyBeanImpl implements MyBean {        public MyBeanImpl(/* params */) {            // let's do whatever one has to        }    }}@Componentpublic class MyConsumerClass {    @Autowired    private MyBeanFactory beanFactory;    public void myMethod() {        // here one has to prepare the parameters        MyBean bean = beanFactory.getMyBean(/* params */);    }}

Now, MyBean is not a spring bean per se, but it is close enough. Dependency Injection works, although I inject the factory and not the bean itself - one has to inject a new factory on top of his own new MyBean implementation if one wants to replace it.

Further, MyBean has access to other beans - because it may have access to the factory's autowired stuff.

And one might apparently want to add some logic to the getMyBean function, which is extra effort I allow, but unfortunately I have no better solution. Since the problem usually is that the dynamic parameters come from an external source, like a database, or user interaction, therefore I must instantiate that bean only in mid-run, only when that info is readily available, so the Factory should be quite adequate.


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

No, not in the way that you mean. The bean representing MyConstructorClass must be configurable without requiring any of its client beans, so MyBeanService doesn't get a say in how MyConstructorClass is configured.

This isn't an autowiring problem, the problem here is how does Spring instantiate MyConstructorClass, given that MyConstructorClass is a @Component (and you're using component-scanning, and therefore not specifying a MyConstructorClass explicitly in your config).

As @Sean said, one answer here is to use @Value on the constructor parameter, so that Spring will fetch the constructor value from a system property or properties file. The alternative is for MyBeanService to directly instantiate MyConstructorClass, but if you do that, then MyConstructorClass is no longer a Spring bean.