简体   繁体   中英

How does @Lazy and proxy bean affect Circular Dependencies in Spring?

Let's look at the following example

    @Service
    class AServiceImpl{

         @Autowired
         BService bservice
    }

    @Service
    class BServiceImpl{

         @Autowired
         AService aservice
    }

I know the Spring uses three-level cache to solve Circular Dependency issues. When A is being initialized and B is being injected, Spring begins to initialize B, which needs bean of A to be injected. But A is not fully initialized yet, so B just get a reference to a non-fully initialized bean of A from cache.

But in Spring, if AService is with a @Transactional annotation, Spring will construct an proxy Bean for A using BeanPostProcessor, and this process happens after @Autowired. This means, although B have aa reference to a non-fully initialized bean of A from cache, the reference is not pointing to the proxy bean, which doesn't seem to be correct. Is there anything wrong with my reasoning?

There is a saying the @Lazy could solve spring Circular Dependencies problem. According to my understanding, there are two types of usage of this annotation.

@Lazy
@Service
class AServiceImpl{

     @Autowired
     BService bservice
}

or

@Service
class BServiceImpl{

     @Lazy
     @Autowired
     AService aservice
}

Some explanation of this annotation says that the annotated bean will be initialized if it is referenced by another bean. But I think whether with it or without it, "the annotated bean will always be initialized if it is referenced by another bean", so how can it solve the circular dependency problem?

Some other explanation says that the annotated bean will be initialized if its methods are invoked, this sound reasonable, but I tried and it seems to me that even if none of methods in AService is called, B can still hold the reference to the final proxy bean of AService, what is wrong with my try?

Another way is inside a constructor

@Autowired
public AService(@Lazy BService bservice) {
    this.bservice = bservice;
}

instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM