“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

SpringbootAOPCause of failure

Today 4YE is here to share a little practical experience with friends. · ∀ ·) Blue

Actual review

(I can’t believe I took so long to write this article… 😵)

Mainly on a Sunday (2020.6.6) in the technology group to see a brother asked

“How to catch custom exceptions with facets?” ( ̄▽ ̄)”

At that time, I thought, isn’t it common to catch exceptions? I often use this global exception catch, so I sent him a small example on my GitHub (mainly the ControllerAdvice annotation), as shown in 👇

The result old brother after a period of time to add me, also asked me if I have time to help to look, also want to call me, MY heart at that time is

Is it so urgent?

When I came back in the evening, it took me two hours to understand why this AOP did not work. Why was the exception not caught?

Now enter the topic 👉 (overall project introduction)

Maven project structure diagram

In this project, maven project adopts multi-module construction, parent and child structure, and the parent Maven unified management of these public packages, as well as the overall version attribute configuration of the project

There are two modules, starter module and core module. The starter module depends on the core module. The overall picture is as follows: 👇

Submodule Introduction

I wonder if you can smell anything when you see the starter above.

At first I thought it would be a common custom starter, but it’s a little different. There’s only a single spring.factories, which clearly uses Springboot’s SPI mechanism.

This is introduced in our previous 👉 Springboot auto-assembly principle exploration article, friends can go to see ~😄

The core parts of the two modules are expanded as follows: 👇

Core project description: Non-Web project only has service, no startup class, etc

👉 because core module is not a Web project!! , so the ControllerAdvice is certainly can’t use, after all, it is in the web in the package, we generally in the web project with the @ ExceptionHandler (Exception. Class) to realize global Exception handling, and then make unified handling.

👉 Springboot’s SPI mechanism tells us that when a Springboot project starts, it scans the meta-INF /spring.factories (including jars) in each project and reads the configuration information in the factories into memory. The auto-configuration will filter these classes according to certain conditions, and finally create the corresponding classes to complete the auto-assembly.

It is obvious that the injection of related beans is done through automatic configuration.

Configuration Class Description

So, with that basic information in mind, we can turn our eyes to xxxConfig, which mimics 👇

Next comes the aspect configuration in the project, such as the small example I wrote earlier: 👇

Code on my GitHub:

Github.com/RyzeYang/sp…

Catch by exception notification

Other than the two above, no other configuration is used in the project!

The question

This is where the problem comes in, after the sections are defined, they don’t work in the project! Everything else works!

So I kept thinking, why is this? It’s already defined…

Finally, I gave it a try, adding this parameter to the YAML configuration file

spring:
  aop:
    auto: true
Copy the code

Because under the impression that this defaults to true, the @enableAspectJAutoProxy will be used by default, without us having to manually add the @enableAspectJAutoProxy annotation (we haven’t manually added this annotation before) 🐖

It didn’t work…

So I decided to manually add it to the xxxConfig config class, but it didn’t work…

@componentScan (basePackages = “com.xxx.xxx”)

And it worked!

So I rushed at 23:59 after the revised document sent to the old brother, but found that he actually fell asleep ha ha ha

The problem analysis

After solving the problem, we can find the problem in the following two points 👇

  1. Section not registered withSpringIOCIn the container
  2. I’m not using this@EnableAspectJAutoProxy

@componentScan (basePackages = “com.xxx.xxx”)

After all, I didn’t need to add it manually before, and from the configuration description, it is enabled by default even if we don’t have the configuration, and it will automatically use this annotation

So do you know the problem of step 2 😄

The @enableAutoConfiguration annotation is the most important one in our SpringBootApplication composite annotation. And that’s what’s going to turn on this auto-assembly of ours.

At this time, I have to move this article out 👉 Springboot auto-assembly principle exploration haha

So let’s take a look at the CONFIGURATION class that AOP auassemble

Configuration classes for AOP auto-assembly

The source code of AopAutoConfiguration is as follows: 👇

There’s a conditional comment at the beginning

@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
Copy the code

HavingValue = “true” means that the value is valid only if it is true

MatchIfMissing = true matchIfMissing = true

Then let’s put our eyes to the first: a static inner class AspectJAutoProxyingConfiguration

As shown in figure 👉 :

If proxyTargetClass is true, it uses cglib. If false, it uses JDK dynamic proxy

Then look at the last of the static inner class: ClassProxyingConfiguration

Can find it here is conditional and AspectJAutoProxyingConfiguration, on the contrary, when there is no class this Advice, help us to register the agent to the IOC

After looking at the AOP auassemble class, we can see that when we use the @EnableAutoConfiguration auassemble annotation and introduce the AOP package, it will automatically assemble the AopAutoConfiguration for us. It uses @enableAspectJAutoProxy, so we usually don’t have to add this annotation manually.

How to test

Hey hey, again a small problem test small partner 😝

SpringBootApplication is not used in the core module, and @enableAutoConfiguration is not used, so this SPI is not useful without auto-assembly. How do we test it in the project

SpringBootTest(classes = xxxConfiguration.class)

With this class, we can directly specify and instantiate the configuration class

I also report a mistake just know ha ha 😝

conclusion

Hey hey, old custom, draw a picture summary below 👇

Thinking of the February

Knowledge map in

So, this time to share this, like friends remember to click like it ~ next time to see the situation and share one of the following 😝

  • Springboot Custom starter
  • Implement plug-ins using AOP
  • The Spring source

The last

Welcome to explore the problem together

If you think this article is good, please support it with more likes 😝

Let’s start this unexpected meeting! ~

Please leave a message! Thanks for your support! ヾ(≧▽≦*)o

I’m 4ye. Next time we should… See you soon!! 😆