欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中創(chuàng)建的AOP不生效的原因及解決

 更新時(shí)間:2021年11月24日 11:13:41   作者:sliby_spe  
這篇文章主要介紹了SpringBoot中創(chuàng)建的AOP不生效的原因及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringBoot 創(chuàng)建AOP不生效的原因

最近在學(xué)習(xí)SpringBoot,今天學(xué)習(xí)了Aop的注冊方式,原理很簡單,配置也很簡單,但是我注冊了切面之后切面一直不生效,是為什么呢?查了好久的資料終于發(fā)現(xiàn)了原因,可以看下圖我的切面注冊類并沒有問題

然后在網(wǎng)上偶然看到可能是主程序掃描的原因,才發(fā)現(xiàn)了原因,可以看到我的顯示方式本來是flat的,那樣的話就很難找出原因了

修改為hirerchical就可以很清楚的看出問題

可以看出,我的主程序和切面類并不在一個(gè)包中,那么主程序掃描不到切面類,自然就不會(huì)注冊切面了,最簡單的解決方式就是在主程序中添加一個(gè)注解@ComponentScan

那么我們就能對springboot有更深入的認(rèn)識(shí),其實(shí)他相對于ssm所有的簡化步驟關(guān)鍵在于主程序,他起到了一個(gè)封裝加載的步驟,不主動(dòng)聲明的情況下他會(huì)掃描和自己在同一個(gè)包下面的所有類,并根據(jù)注解自動(dòng)注冊,那么以后寫項(xiàng)目時(shí)最好的方式就是將主程序放在主包下,然后所有的這些類都放在子包中即可

SpringBoot aop無效的情況

項(xiàng)目結(jié)構(gòu)

在這里插入圖片描述

package com.example.demo.inter;
public interface CustomerService {
     void doSomething1();
     void doSomething2();
}
package com.example.demo.inter;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
@Service
public class CustomerServiceImpl implements CustomerService {
    @Override
    public void doSomething1() {
        System.out.println("CustomerServiceImpl.doSomething1()");
        doSomething2();
        ((CustomerService) AopContext.currentProxy()).doSomething2();
    }
    @Override
    public void doSomething2() {
        System.out.println("CustomerServiceImpl.doSomething2()");
    }
}
package com.example.demo;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class CustomerServiceInterceptor {
    @Before("execution(* com.example.demo.inter..*.*(..))")
    public void doBefore() {
        System.out.println("do some important things before...");
    }
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy(proxyTargetClass=true, exposeProxy=true)
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
package com.example.demo;
import com.example.demo.inter.CustomerService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
    @Autowired
    CustomerService customerService;
    @Test
    public void testAOP() {
        customerService.doSomething1();
    }
    @Test
    void contextLoads() {
    }
}

運(yùn)行下testAOP,為啥doSomething2()沒有切面效果,使用AopContext.currentProxy就可以了?

攔截器的實(shí)現(xiàn)原理就是動(dòng)態(tài)代理,實(shí)現(xiàn)AOP機(jī)制。Spring 的代理實(shí)現(xiàn)有兩種:一是基于 JDK Dynamic Proxy 技術(shù)而實(shí)現(xiàn)的;二是基于 CGLIB 技術(shù)而實(shí)現(xiàn)的。如果目標(biāo)對象實(shí)現(xiàn)了接口,在默認(rèn)情況下Spring會(huì)采用JDK的動(dòng)態(tài)代理實(shí)現(xiàn)AOP,CustomerServerImpl正是這種情況。

JDK動(dòng)態(tài)代理生成的CustomerServiceImpl的代理類翻譯過來如下:

package com.example.demo;
import com.example.demo.inter.CustomerService;
public class CustomerServiceProxy implements CustomerService {
    private CustomerService customerService;
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }
    public void doSomething1() {
        doBefore();
        customerService.doSomething1();
        // 默認(rèn),所以不會(huì)執(zhí)行doBefore
        customerService.doSomething2();
        // 加入 AopContext.currentProxy的效果,完成切面效果
        this.doSomething2();
    }
    public void doSomething2() {
        doBefore();
        customerService.doSomething2();
    }
    private void doBefore() {
        System.out.println("do some important things before...");
    }
}

這樣很直觀地明白為啥要使用AopContext.currentProxy了。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MyBatis開發(fā)Dao層的兩種方式實(shí)現(xiàn)(原始Dao層開發(fā))

    MyBatis開發(fā)Dao層的兩種方式實(shí)現(xiàn)(原始Dao層開發(fā))

    這篇文章主要介紹了MyBatis開發(fā)Dao層的兩種方式實(shí)現(xiàn)(原始Dao層開發(fā)),并對數(shù)據(jù)庫進(jìn)行增刪查改,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java實(shí)現(xiàn)抽獎(jiǎng)算法的示例代碼

    Java實(shí)現(xiàn)抽獎(jiǎng)算法的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)抽獎(jiǎng)算法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-04-04
  • Java?Cloneable接口的深拷貝與淺拷貝詳解

    Java?Cloneable接口的深拷貝與淺拷貝詳解

    這篇文章主要為大家詳細(xì)介紹了Java?Cloneable接口的深拷貝與淺拷貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java中的Comparable和Comparator接口

    Java中的Comparable和Comparator接口

    這篇文章主要介紹了Java中的Comparable和Comparator接口,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • Java?BigDecimal正確用法詳解

    Java?BigDecimal正確用法詳解

    Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數(shù)進(jìn)行精確的運(yùn)算。雙精度浮點(diǎn)型變量double可以處理16位有效數(shù),但在實(shí)際應(yīng)用中,可能需要對更大或者更小的數(shù)進(jìn)行運(yùn)算和處理
    2022-10-10
  • Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例

    Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例

    這篇文章主要介紹了Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例,注解是一種能被添加到j(luò)ava代碼中的元數(shù)據(jù),類、方法、變量、參數(shù)和包都可以用注解來修飾,注解對于它所修飾的代碼并沒有直接的影響,需要的朋友可以參考下
    2023-09-09
  • java如何通過IP解析地理位置

    java如何通過IP解析地理位置

    這篇文章主要介紹了java如何通過IP解析地理位置的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 淺談Java中是否直接可以使用enum進(jìn)行傳輸

    淺談Java中是否直接可以使用enum進(jìn)行傳輸

    這篇文章主要介紹了淺談Java中是否直接可以使用enum進(jìn)行傳輸,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 基于java高并發(fā)處理方案

    基于java高并發(fā)處理方案

    這篇文章主要介紹了基于java高并發(fā)處理方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    java實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)籍管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評論