Penemubual: Anotasi biasa Spring Aop dan urutan pelaksanaan
Baru-baru ini, semasa saya menyemak resume dan melakukan temu duga olok-olok untuk ramai orang, beberapa rakan memberi saya maklum balas tentang soalan temuduga Spring AOP, dan saya akan bertanya kepada mereka hari ini.
Perkara yang paling berkuasa tentang Spring pada mulanya ialah dua fungsi teras IOC / AOP Hari ini kita akan mempelajari anotasi biasa dan urutan pelaksanaan Spring AOP.
Mata teras temu bual Spring:
IOC, AOP, Suntikan kacang, Kitaran hayat kacang, Kebergantungan bulat kacang
Pertama sekali, mari semak beberapa anotasi yang biasa digunakan dalam gaya Aop Spring:
- ="font-size: 14px; padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font- family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@Sebelum Prapemberitahuan: dilaksanakan sebelum kaedah sasaran
@Before
前置通知:目标方法之前执行 @After
后置通知:目标方法之后执行(始终执行)@AfterReturning
返回之后通知:执行方法结束之前执行(异常不执行)@AfterThrowing
异常通知:出香异常后执行@Around
@After
post notification : Dilaksanakan selepas kaedah sasaran (sentiasa dilaksanakan)
@ AfterReturning
Pemberitahuan selepas pemulangan: Dilaksanakan sebelum kaedah pelaksanaan tamat (pengecualian tidak dilaksanakan) @AfterThrowing
Pemberitahuan pengecualian: Dilaksanakan selepas pengecualian kemenyan
@Around
Around notification: Perlaksanaan kaedah surround target
Contoh kod
Mari cepat bina program demo spring aop untuk membincangkan beberapa butiran spring aop.
Fail konfigurasi
Untuk memudahkan saya menggunakan spring-boot secara langsung untuk pembinaan projek pantas, anda boleh menggunakan fungsi penciptaan pantas projek spring-boot bagi idea, atau pergi ke start.spring.io
上面去快速创建spring-boot 应用。
因为本人经常手动去网上贴一些依赖导致,依赖冲突服务启动失败等一些问题。
plugins { id 'org.springframework.boot' version '2.6.3' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group 'io.zhengsh' version '1.0-SNAPSHOT' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } maven { url 'https://repo.spring.io/snapshot' } } dependencies { # 其实这里也可以不增加 web 配置,为了试验简单,大家请忽略 implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-aop' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
接口类
首先我们需要定义一个接口。我们这里可以再来回顾一下 JDK 的默认代理实现的选择:
如果目标对象实现了接口,则默认采用JDK动态代理 如果目标对象没有实现接口,则采用进行动态代理 如果目标对象实现了接口,且强制Cglib,则使用cglib代理
这块的逻辑在 DefaultAopProxyFactory
Oleh kerana saya sering menyiarkan beberapa kebergantungan secara manual dalam talian, konflik kebergantungan berlaku Terdapat beberapa masalah seperti kegagalan permulaan perkhidmatan.
public interface CalcService { public int div(int x, int y); }
Kelas antara muka
Mula-mula kita perlu mentakrifkan antara muka. Di sini kita boleh menyemak pilihan pelaksanaan proksi lalai JDK:
Jika objek sasaran Jika antara muka dilaksanakan, proksi dinamik JDK digunakan secara lalai Jika objek sasaran tidak melaksanakan antara muka, gunakan proksi dinamik Jika objek sasaran melaksanakan antara muka dan memaksa Cglib, gunakan proksi cglib
Logik bagi bahagian ini dalam< code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font- family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">DefaultAopProxyFactory Jika anda berminat , anda boleh lihat.
🎜Di sini kita hanya akan melakukan operasi bahagi, yang boleh mensimulasikan operasi biasa dan juga mudah mensimulasikan ralat. 🎜 Kelas pelaksanaan@Aspect @Component public class MyAspect { @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))") public void divPointCut() { } @Before("divPointCut()") public void beforeNotify() { System.out.println("----===>> @Before 我是前置通知"); } @After("divPointCut") public void afterNotify() { System.out.println("----===>> @After 我是后置通知"); } @AfterReturning("divPointCut") public void afterReturningNotify() { System.out.println("----===>> @AfterReturning 我是前置通知"); } @AfterThrowing("divPointCut") public void afterThrowingNotify() { System.out.println("----===>> @AfterThrowing 我是异常通知"); } @Around("divPointCut") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object retVal; System.out.println("----===>> @Around 环绕通知之前 AAA"); retVal = proceedingJoinPoint.proceed(); System.out.println("----===>> @Around 环绕通知之后 BBB"); return retVal; } }
其实这块我刚开始也不是很理解,但是我看了 Aspect 注解的定义我就清楚了

这里面根本就没有 Bean 的定义。所以我们还是乖乖的加上两个注解。
还有就是如果当测试的时候需要开启Aop 的支持为配置类上增加@EnableAspectJAutoProxy
注解。
其实 Aop 使用就三个步骤:
定义 Aspect 定义切面 定义 Pointcut 就是定义我们切入点 定义具体的通知,比如: @After, @Before 等。
@Aspect @Component public class MyAspect { @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))") public void divPointCut() { } @Before("divPointCut()") public void beforeNotify() { System.out.println("----===>> @Before 我是前置通知"); } @After("divPointCut") public void afterNotify() { System.out.println("----===>> @After 我是后置通知"); } @AfterReturning("divPointCut") public void afterReturningNotify() { System.out.println("----===>> @AfterReturning 我是前置通知"); } @AfterThrowing("divPointCut") public void afterThrowingNotify() { System.out.println("----===>> @AfterThrowing 我是异常通知"); } @Around("divPointCut") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object retVal; System.out.println("----===>> @Around 环绕通知之前 AAA"); retVal = proceedingJoinPoint.proceed(); System.out.println("----===>> @Around 环绕通知之后 BBB"); return retVal; } }
测试类
其实我这个测试类,虽然用了 @Test 注解,但是我这个类更加像一个 main 方法把:如下所示:

执行结论
结果记录:spring 4.x, spring-boot 1.5.9
无法现在依赖,所以无法试验
我直接说一下结论:Spring 4 中环绕通知是在最里面执行的
结果记录:spring 版本5.3.15 springboot 版本2.6.3

多切面的情况
多个切面的情况下,可以通过@Order指定先后顺序,数字越小,优先级越高。如下图所示:

代理失效场景
下面一种场景会导致 aop 代理失效,因为我们在执行 a 方法的时候其实本质是执行 AServer#a
的方法拦截器(MethodInterceptor
)链, 当我们在 a 方法内直接执行b(), 其实本质就相当于 this.b() , 这个时候由执行 a方法是调用到 a 的原始对象相当于是 this 调用,那么会导致 b() 方法的代理失效。这个问题也是我们开发者在开发过程中最常遇到的一个问题。
@Service public class AService { public void a() { System.out.println("...... a"); b(); } public void b() { System.out.println("...... b"); } }
Atas ialah kandungan terperinci Penemubual: Anotasi biasa Spring Aop dan urutan pelaksanaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Square Root di Java. Di sini kita membincangkan cara Square Root berfungsi di Java dengan contoh dan pelaksanaan kodnya masing-masing.

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Penjana Nombor Rawak di Jawa. Di sini kita membincangkan Fungsi dalam Java dengan contoh dan dua Penjana berbeza dengan contoh lain.

Panduan untuk Nombor Armstrong di Jawa. Di sini kita membincangkan pengenalan kepada nombor Armstrong di java bersama-sama dengan beberapa kod.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah
