membersound
membersound

Reputation: 86925

How to autowire a class with non-empty constructor?

I'd like to @Autowired a class that has a non-empty constructor. Just the the following as an example, it does not necessairly have to be a view/service. Could be whatever component you like, having non-default constructor:

@Component
class MyViewService {
  //the "datasource" to show in the view
  private List<String> companies companies;
  private MyObject obj;

  public MyViewService(List<String> companies, MyObject obj) {
    this.companies = companies;
    this.obj = obj;
  }
}

Of course I cannot just write

@Autowired
private MyViewService viewService;

as I'd like to use the constructor with the list. But how?

Are there better approaches than refactoring these sort of constructors to setters? I wouldn't like this approach as ideally the constructor forces other classes to provide all objects that are needed within the service. If I use setters, one could easily forget to set certain objects.

Upvotes: 0

Views: 2666

Answers (2)

Paul
Paul

Reputation: 20091

If you want Spring to manage MyViewService you have to tell Spring how to create an instance of it. If you're using XML configuration:

<bean id="myViewService" class="org.membersound.MyViewService">
  <constructor-arg index="0" ref="ref_to_list" />
  <constructor-arg index="1" ref="ref_to_object" />
</bean>

If you're using Java configuration then you'd call the constructor yourself in your @Beanannotated method.

Check out the Spring docs on this topic. To address a comment you made to another answer, you can create a List bean in XML as shown in the Spring docs. If the list data isn't fixed (which it's probably not) then you want to use an instance factory method to instantiate the bean.

In short, the answers you seek are all in the Spring docs :)

Upvotes: 2

DwB
DwB

Reputation: 38338

If a component has a non-default constructor then you need to configure the constructor in the bean configuration.

If you are using XML, it might look like this (example from the spring reference document):

<beans>
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
    </bean>

    <bean id="bar" class="x.y.Bar"/>
    <bean id="baz" class="x.y.Baz"/>
</beans>

The key here is constructor wiring of the bean that will be used for the @AutoWire. The way you use the bean has no impact.

Upvotes: 0

Related Questions