1

I'd like to know what are the differences between the two examples below. One is using @PostConstruct init method to ensure autowired bean is initialized, and the other one is using constructor with @Autowired to ensure any needed beans are initialized.

I am curious

  1. If there is any functional differences
  2. If one is better than the other, why? (Maybe initialization speed, less call stack, less memory usage, etc.)

Thanks in advance :)

@Component
public class MyBean {

    @Autowired
    public MyBean(SomeOtherBean someOtherBean) {
        ...
    }
    ...
}
@Component
public class MyBean {

    @Autowired 
    private SomeOtherBean someOtherBean;

    @PostConstruct
    public void init() {
        ...
    }
    ...
}
Edmund Ham
  • 47
  • 1
  • 7
  • 2
    To give a good answer, i'd need to know what you plan to do in your PostConstruct. In general, PostConstruct is executed AFTER the bean is created. You can see this post for more info: https://www.baeldung.com/running-setup-logic-on-startup-in-spring – Tom Cools Apr 17 '20 at 20:57
  • 1
    Also, Autowired on the Constructor is the most accepted approach, instead of putting autowired on a field. https://stackoverflow.com/questions/3746574/where-is-the-autowired-annotation-supposed-to-go-on-the-property-or-the-metho – Tom Cools Apr 17 '20 at 20:59
  • The use case is different. ```@Autowired``` is used for dependency injection, which is resolved in intitialization. ```@PostConstruct``` is run after initialization, meaning you can already use your dependencies. See also: https://stackoverflow.com/questions/3406555/why-use-postconstruct – Pieterjan Deconinck Apr 17 '20 at 21:01

2 Answers2

2

in the first case, if I'm going to use MyBean.class without in a none Spring framework project I'll need to pass SomeOtherBean so I know the object is created correctly. but in the second case, I would have done new MyBean() and then after I'll get NullPointerException when using it because the object depends on SomeOtherBean. so the first one is much cleaner.

stacker
  • 4,317
  • 2
  • 10
  • 24
-2

Autowired constructor will not create the instance unless it has someotherbean available, that means it fast fails and will not even try to create the instance before someotherbean is available. If you do not have an autowired constructor it will create the instance and the bean is available in container, then inject the someotherbean when it is available. Whatever inside the @PostConstruct annotated method will execute after the instance is created. Please read the following will get better idea

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#spring-core

SHAKU
  • 657
  • 5
  • 15
  • 1
    Field injection will fail just the same as constructor injection if a requested bean is not available. – Savior Apr 17 '20 at 21:09
  • @Savior Agree, but the container behaves little differently. The instance will wait for the field injected beans to come up and if not available then fails. – SHAKU Apr 17 '20 at 21:14
  • What do you mean by _will wait_? For both cases, Spring will look at the application context (bean factory) and instantiates corresponding instances for the request beans (if those haven't been instantiated already), and fail if the beans don't exist. – Savior Apr 17 '20 at 21:17