Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Spring framework autowire a collection

I've never seen an autowired collection:

@Service
public class SomeFactory {
    @Autowired
    private List<Foo> foos;

    @PostConstruct
    public void init() {
        for(Foo foo: foos) { 
            //do something
        }
    }
}

In init() method, I can see foos has several entries already. I guess Spring knows who's supposed to be the entry of foos. But, how? What should I do if I want to add a Foo object into foos? Need to configure in a property file, or any other idea?

like image 857
choiapril Avatar asked Jun 20 '16 05:06

choiapril


2 Answers

Spring's BeanFactory is basically a registry of beans. These beans can be declared using XML, or using @Bean-annotated methods in a Configuration class, or be automatically discovered using package scanning.

When you ask for a List<Foo>, Spring finds all the beans that are of type Foo, creates a List containing those beans, and injects that list.

The documentation about Autowired explains it, BTW:

It is also possible to provide all beans of a particular type from the ApplicationContext by adding the annotation to a field or method that expects an array of that type

like image 81
JB Nizet Avatar answered Sep 28 '22 07:09

JB Nizet


In init() method, I can see foos has several entries already. I guess Spring knows who's supposed to be the entry of foos. But, how?

When the Application Context / Bean Factory is created, by default (if not specify otherwise with lazy init or non singleton scope), all the beans are also created. The app context knows about these beans. So when we try to @Autowire collections of a particular type beans like private List<Foo> foos;, Spring find all foos, add them to list and inject into the dependent bean.

What should I do if I want to add a Foo object into foos? Need to configure in a property file, or any other idea?

There are multiple ways to do it. Can choose one suitable option, based on requirement.

  • Declare the beans in an bean configuration XML file. Flexible. But you may not like doing it in XML.
  • @Component annotation on a bean class. The class will be scanned by Spring with Component Scan configured. No XML but less flexible. Bean class definition and declaration are tightly coupled. Can not create the @Component bean in a different Application Context.
  • @Bean annotation on a method that returns the bean inside an @Configuration annotated class. Preferable. Bean class definition and declaration are decoupled and done though annotation only. We can create the @Bean annotated bean from the method in a different Application Context as well.
like image 29
Dexter Avatar answered Sep 28 '22 08:09

Dexter