org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name

created at 05-26-2022 views: 220

background

Today, when merging the code and packaging it, I suddenly found that the code is running.

Pull out the error log and have a look, good guy, the error log prints a lot

 "timestamp":"2022-05-23 22:30:47.544",
                    "level": "ERROR",
                    "thread": "main",
                    "class": "o.springframework.boot.SpringApplication",
                    "message": "Application run failed" }

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contentAspect': Unsatisfied dependency expressed through field 'topicService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'topServiceImpl': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'storeOrderService';
...

According to the wrong feedback, it should be an error when initializing bean.

Then each Service calls other service. This leads to an avalanche of error message output.

Fortunately, the code is in a fast integration mode.

Compare the code before the error with the code after the error.

It was found that a code change in only one place may have caused the problem.

identify the problem

According to personal habits, first find out the code that caused the error and compare the code.

code before modification

@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityDao, ActivityEntity> implements ActivityService {

    private final CorrelationService  correlationService;
    private final RecordService recordService;


    public ActivityServiceImpl(CorrelationService correlationService,
                                        RecordService recordService) {
        this.correlationService = correlationService;
        this.recordService = recordService;
    }

...

Modified code

@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityDao, ActivityEntity> implements ActivityService {

    private final CorrelationService  correlationService;
    private final RecordService recordService;
    private final OrderService orderService;

    public ActivityServiceImpl(CorrelationService correlationService,
                                        RecordService recordService,
                                        OrderService orderService) {
        this.correlationService = correlationService;
        this.recordService = recordService;
        this.orderService = orderService;
    }

...

I found that the code in two places is just one more initialization of service.

Note: This method of initialization is IDEA's recommended solution.

Normally, there should be no problem.

But since there is a problem, let's go over the error message carefully (to be honest, it does look like a lot of effort if the English is not good. Fortunately, the Error creating bean with name related to the middle loop can be omitted, and you can skip directly to the error related to the back. and suggestions section.

....
Bean with name 'orderServiceImpl' has been injected into other beans [ActivityServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped. 
This means that said other beans do not use the final version of the bean. 
This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.

The information about this error drew attention.

Bean with name 'orderServiceImpl' has been injected into other beans [ActivityServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped

According to this statement, orderServiceImpl has been occupied by ActivityServiceImpl (injected), and it is also part of the circular reference.

solution

Circular reference, then this problem is simple.

For the solution to circular references, that's all paediatric work.

Solution 1: Split

It is enough to disassemble the original circular reference part so that the two servies are no longer circularly referenced.

Solution 2: Use Spring's solution

In general, spring helps us solve the problem of circular dependencies.

But in the above case, spring is not used.

So we need to judge whether the code will be circularly dependent.

The solution is relatively simple. Kill the constructor, use @Autowried directly, and add @Lazy to double insurance.

Note that if @Ansyc is used in the code, spring may not have a way to automatically resolve circular dependencies.

For details, please refer to this article

Solution 3: Use the singleton way

It is to use the static method to determine whether the current object already exists.

add a new one if it doesn't exist. Because it is the only one, so there will be no such troubles

Summarize

  1. When there is a problem, the quickest way is to compare the problem before and after the problem, and find the problem and solve it first. The ability at work is very important, but the boss values your ability to solve the problem.

  2. In order not to repeat the same problem, it is necessary to delve into the problem behind it:

Including what caused the problem;

What is the idea of ​​the intermediate solution (what solutions are there and which is the best);

In the follow-up words, what pits like this should be avoided here, so as to avoid the existence of future generations.

created at:05-26-2022
edited at: 05-26-2022: