Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Bean: Is autowired attribute initialised before constructor?

Tags:

spring

@Component
public class BeanA {
...
}


@Component
public class BeanB {

    @Autowired
    BeanA beanA;

    public BeanB() {
        // Use beanA
        beanA.method();
    }
}

Can we assume BeanA is created and initialized before BeanB constructor is called? (I know we can pass BeanA as constructor arg to BeanB, this is more of curiosity question to understand spring/java initialisation sequence)

like image 889
gammay Avatar asked Oct 07 '14 07:10

gammay


People also ask

Is @autowired needed on constructor?

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with. However, if several constructors are available, at least one must be annotated to teach the container which one to use.

What happens when you Autowire a constructor?

This mode is very similar to byType, but it applies to constructor arguments. Spring container looks at the beans on which autowire attribute is set constructor in the XML configuration file. It then tries to match and wire its constructor's argument with exactly one of the beans name in the configuration file.

What is the difference between Autowired and constructor injection?

You can annotate fields and constructor using @Autowired to tell Spring framework to find dependencies for you. The @Inject annotation also serves the same purpose, but the main difference between them is that @Inject is a standard annotation for dependency injection and @Autowired is spring specific.

Which of the following statement is correct about @autowired annotation?

Spring Certification Question: Which of the following is true regarding the @Autowired annotation? Select Your Answer: A: It is 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.


3 Answers

Take a look at http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-autowired-annotation-qualifiers

Setting properties on bean would happen after it is constructed by means of a constructor or a factory method. By default, beans are autowired by name and values are set using setter methods. So in your case the field will be set after constructor.

This is because

@Autowired
BeanA beanA;

really means that you want to autowire the field of that class instance. beanA in your case is not really a constructor arg. (Well, here is a quick question, are the constructor argument names retained after compilation? Is there any debug flag related to this?)

As this example from spring documentation says, you can apply @Autowired to constructors and fields:

public class MovieRecommender {

    @Autowired
    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...

}

Let me know if you need any more help with this.

Oh, and just a minor point. You seem to be calling method() on beanA in your constructor. It is not a good idea, if the method can be overridden. I know it is just an example you jotted down here, but just a word of caution.

like image 171
Atul Avatar answered Oct 07 '22 06:10

Atul


No, the autowiring is handled by a BeanPostProcessor that will run after the constructor of the newly created bean. If, for some reason, you need to autowire some fields and then run some initialisation you can use a @PostConstruct annotated method. It will be called after all dependencies are injected. In most cases @Autowiring a constructor (and, perhaps, making the object immutable) is still the best option.

like image 25
Apokralipsa Avatar answered Oct 07 '22 06:10

Apokralipsa


No, spring is very clever, but not that magical ... Internally, spring :

  • creates an instance
  • set instances properties
  • stores eventually the bean in relevant scope (exept for prototype beans) and/or gives it to caller

But the creation uses a constructor and at the time it is called properties have not been set.

like image 21
Serge Ballesta Avatar answered Oct 07 '22 07:10

Serge Ballesta