AberonMan / spring-early-init-demo

1 stars 2 forks source link

Explanation from youtube video #1

Closed wind57 closed 6 months ago

wind57 commented 6 months ago

I was watching the video you put up on youtube and I found the explanations you have for that NullPointerException a bit too "thin" and while you did indeed understand the problem at hand, the explanation given is not accurate, at least it's not complete.

The idea to make such a video and explain how BeanFactoryPostProcessor works is great, it just needs to be amended here and there. I hope you don't mind me opening such a discussion.

The NullPointerException is not coming of the result of the creation of PokemonFactoryBean. If you properly debug the code, you will notice that PokemonFactoryBean is created just fine, indeed because of that eager init flag that is set to true. Granted, you do understand correct that once PokemonFactoryBean bean is created, it needs a bean of type PokemonConfigurationProperties simply because both of its constructors take it as argument , and Spring creates a "partial" bean for it (without any of its fields being filled).

The exception comes from the second factory: PokemonMasterFactoryBean. Same init flag that is set to true is causing this bean to be created, but its constructor:

    public PokemonMasterFactoryBean(PokemonDsl dsl, Pokemon pokemon) {
        this.dsl = dsl;
        this.pokemon = pokemon;
    }

says that it needs an instance of Pokemon. So Spring does a very simple thing: tries to find/create one. Since one such bean does not exist, PokemonFactoryBean::getObject will be invoked and this is where that partial PokemonConfigurationProperties matters. This is where calling any method on that instance will return a null, because as you already noted its too early for its fields to be populated, thus that NullPointerException.


What might confuse someone (as me) about your explanation, is that around 25:14 you are stating that fields from PokemonConfigurationProperties are populated (for the GenericFactoryBeanApplication), which is not correct. Those fields are not populated either, but it does not matter because no one actually needs a Pokemon bean for that example, as such PokemonFactoryBean::getObject is not called at all, thus you do not see that exception.

804 commented 6 months ago

Hello!

Thanks a lot for your question and attention you payed to our meetup.

Yes, I absolutely agree with your comment. Our purpose was to show that starting GenericFactoryBeanApplication can't lead to NullPointerException inside PokemonFactoryBean::getObject. But you're right , there was no any PokemonFactoryBean::getObject call. So we need to improve our GenericFactoryBeanApplication demo part with configuring some new bean with our Pokemon beans as dependencies. It will be fair enough, such configuration leads to PokemonFactoryBean::getObject call.

wind57 commented 6 months ago

Sorry for not replying earlier, was on vacation.

Thx for acceptance! I'll close this one since we agreed on it.