0

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.

membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

2

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 :)

Paul
  • 19,704
  • 14
  • 78
  • 96
  • OK I see. But one question remains taking eg my example: is it good practice to make data-supplying lists a spring-managed bean? I mean, this list would be probably only used for this particular service, and only in this constructor. – membersound Jun 18 '14 at 13:29
  • It's not a bad practice - it just depends on the problem you're trying to solve. If the elements of the list are known in advance then it's better to put them into a properties file and have Spring inject the values from the file. – Paul Jun 18 '14 at 13:35
  • You can actually use list tags to specify the list in-place! See http://stackoverflow.com/questions/2416056/how-to-define-a-list-bean-in-spring – flup Jun 18 '14 at 13:42
0

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.

DwB
  • 37,124
  • 11
  • 56
  • 82
  • Taking my example, how would I make a `List companies` a spring managed bean? Does it make sense at all to have a list of objects managed? – membersound Jun 18 '14 at 13:26
  • If you are using XML, configure a util:list bean that contains the list of companies. the Paul answer demonstrates this. – DwB Jun 18 '14 at 13:49