Search code examples
javaspringdependency-injectionjls

How does spring resolve method calls as beans?


Consider this code:

public class Bean1  {}

public class Bean2  {
    private final Bean1 bean1;

    public Bean2(Bean1 bean1){
        this.bean1 = bean1;
    }
}

@Configuration
public class MyConfiguration {
    @Bean
    public Bean1 bean1(){
        return new AImpl(); 
    }

    @Bean 
    public Bean2 bean2() {
        return new BImpl(bean1());
    }

    @Bean
    public Bean3 bean3() {
        return new BImpl(bean1());
    }
}

My knowledge of Java dicates, that two references of bean1 in bean2 and bean3 should be different, that, since I call the bean1() method twice, two different objects should be created.

However, under Spring, in the same ApplciationContext, etc. etc., both bean2 and bean3 will have the same reference to the same object of class Bean1.

How is that possible in Java? What mechanism does Spring use that allows it to somehow intercept method calls and put beans as result of those calls?


Solution

  • Class with the @Configurable annotation are treated in a special way. They are parsed using ASM and from the scanning special bean definitions are created. Basically each @Bean annotation is a special kind of factory bean.

    Because the methods are treated as factory beans they are only invoked once (unless the scope isn't singleton of course).