preface

One type of circular dependency is self-injection: self dependence.

Self-injection of transactions

How did you resolve the failure of self-invoking transactions in Spring? Some friends suggest that you can inject yourself to solve transaction failures.

The specific usage is as follows:

@slf4j @service Public class OrderBizServiceImpl implements OrderBizService {// Add to OrderBizService @autoWired private OrderBizService  orderBizService; @override public void callBack() throws Exception {// A series of logical // transactions are required to update orders and user amounts orderBizService.updateOrderStatusAndUserBalance(); } @Override @Transactional(rollbackFor = Exception.class) public void updateOrderStatusAndUserBalance() throws Exception {// Inside is transaction logic}}Copy the code

Did you find something amazing, the transaction works.

In fact, this injection itself, is actually a proxy object injected, called transaction, is also called the proxy object of the transaction, so the transaction takes effect.

Spring transaction failure causes:

Transactions are valid only when applied to public methods; Transactions need to be invoked from the outside, and Spring calls themselves are invalidated; It is recommended that the Transactional annotation @Transactional be generally added to the implementation class.

Asynchronous self-injection

It was discovered that the @Transactional annotation could self-inject to solve the problem of transaction failures. During one development, it naturally occurred to me that @async Async could also self-inject to solve the problem of loop dependencies.

NO, NO, NO…

The facts tell us no!

Start with mistakes:

Start pushing back up the exposedObject == bean is where the problem is.

That is, asynchronously, the second level cache is not the same as the original one.

Object earlySingletonReference = getSingleton(beanName, false);

This time the fetch was found to be different, so an error was reported.

Debug, following the logic of loop dependencies, executes the populateBean, assigns the property, finds the dependency itself, and creates its own.

Execute the singleton.getobject method

While performing getEarlyBeanReference judgement InfrastructureAdvisorAutoProxyCreator true wrapIfNecessary call first determine whether to generate a proxy object, there is no generated proxy objects.

And then began to perform asynchronous AsyncAnnotationBeanPostProcessor judgment to false. So no asynchronous generation proxy object logic is performed.

So keep reading

Into initializeBean logic, some called applyBeanPostProcessorsAfterInitialization

Side buddy search, so post out code keywords. IDEA uses ⌘ + Shift + F to search.

Looping post-processor:

Found after execution AsyncAnnotationBeanPostProcessor the PostProcessor, objects are changed. This results in the second level cache being different from the current Bean.

This is why @async self-invocation does not work because the object is modified by the agent later in the initialization phase.

Why would @Transactional work?

First determine InfrastructureAdvisorAutoProxyCreator true generates a proxy objects.

Transaction processor PersistenceExceptionTranslationPostProcessor no execution.

Focus on applyBeanPostProcessorsAfterInitialization continue to Debug

When the execution ends, the Bean is not changed.

conclusion

1.@Transactional: proxy objects are generated when cyclic dependencies are raised from level 2 cache to level 3 cache.

2.@Async: The proxy object is generated during the initialization phase (initializeBean). Then @async causes the exposedObject == bean to be later determined to be false, thus throwing an exception.

There are other places after execution processor, such as applyBeanPostProcessorsBeforeInitialization, just focus on the two here.

@Transactional generates a proxy object at getEarlyBeanReference. @Async generates a proxy object at getEarlyBeanReference. So it doesn’t pass.

The last

I have arranged a: Spring family barrel series, Java systematic information, (including Java core knowledge, interview topics and the latest Internet real questions in 20 years, e-books, etc.) friends who need to pay attention to the public number can be obtained.