3

I have following classes:

@Repository
class A {

    public void method1() {
        ...
    }
}

@Component
class B implements C {

    @Autowired
    @Lazy
    private A a;

    public void method2() {
        a.method1();
    }
}

@Component
class D {

    @Autowired
    private List<C> c;

    @PostConstruct
    public void method3() {
        // iterate on list c and call method2()
    }
}

Let's suppose Spring initializes the beans as following:
1. First bean B is created. When bean B is being created, field a will not be initialized because of the @Lazy annotation.
2. Next bean D is created. Then method3() will get executed as it is marked with @PostConstruct, but bean A is not yet touched by Spring. So when a.method1() will be called, then will Spring create bean A and inject it into the field a or will it throw a NullPointerException?

rohanagarwal
  • 771
  • 9
  • 30
  • 2
    Did you tried running the same set up? – Arpit Aggarwal Jan 03 '17 at 12:19
  • @Arpit Yes I did and it did inject A into a. But I can't guarantee whether Spring will first come to A or to D. If it first comes to A, it will be able to inject A into a while executing method3(). If it first comes to D, then the problem may arise. – rohanagarwal Jan 03 '17 at 12:23

1 Answers1

10

You need to understand, what's going on when you're specifying @Lazy as part of injection. According to documentation:

In addition to its role for component initialization, the @Lazy annotation may also be placed on injection points marked with @Autowired or @Inject. In this context, it leads to the injection of a lazy-resolution proxy.

This means that on start Spring will inject instance of proxy class instead of instance of class A . Proxy class is automatically generated class that have same interface as class A. On first call of any method proxy will create instance of class A inside of self. After that all calls of methods will be redirected to this instance of class A inside of proxy.

So there is no reason to be afraid of any problems.

Ken Bekov
  • 13,696
  • 3
  • 36
  • 44
  • 1
    I did test this and yes it works. I have verified that NPE will not be thrown and a(instance of A) is created on first call. Adding a bit explanation about proxies to make things more clear: A proxy is a surrogate object or placeholder for another object to control access to it. Because the proxy sits in between the caller of an object and the real object itself, it can decide to prevent the real (or target) object from being invoked, or do something before the target object is invoked. – rohanagarwal Jan 03 '17 at 14:53