Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring bean lazy initialization

I was thinking about the lazy-initialization of beans in Spring. For me, it wasn't crystal clear that the "lazy" here means that a bean will be created when it's referenced.

I expected that the lazy initialization support in Spring is different. I thought this is a "method-call" based lazy creation. What I mean by this is, whenever any method is being called on the method, it will be created.

I think this could be easily solved by creating a proxy instance of the specific bean and do the initialization on any method call.

Am I missing something why this is not implemented? Is there any problem with this concept?

Any feedback/idea/answer will be appreciated.

like image 605
Arnold Galovics Avatar asked Apr 23 '16 20:04

Arnold Galovics


1 Answers

You can achieve the behavior you want by scoping your bean with a proxyMode of ScopedProxyMode.TARGET_CLASS (CGLIB) or ScopedProxyMode.INTERFACES (JDK).

For example

public class StackOverflow {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Conf.class);
        Bar bar = ctx.getBean(Bar.class);
        System.out.println(bar);
        System.out.println(bar.foo.toString());
    }
}

@Configuration
class Conf {
    @Bean
    @Lazy
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Foo foo() {
        System.out.println("heyy");
        return new Foo();
    }

    @Bean
    public Bar bar() {
        return new Bar();
    }
}

class Bar {
    @Autowired
    public Foo foo;
}

class Foo {
}

will print

com.example.Bar@3a52dba3
heyy
com.example.Foo@7bedc48a

demonstrating that the Foo bean was initialized through its @Bean factory method only after a method was invoked on the Foo instance injected by the Spring context in the Bar bean.

The @Scope annotation can be used in a class declaration as well.

like image 184
Savior Avatar answered Oct 12 '22 09:10

Savior