【Spring基礎(chǔ)】Spring 中的 AOP框架

什么是AOP

OOP(面向?qū)ο缶幊?提供“從上到下”的關(guān)系,而AOP(面向方面編程)提供一種“橫切”的方式,也可以說是“從左到右”。
簡單來說就是將那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護(hù)性。

實(shí)例

可能光是說AOP的定義,大家都不太能理解。
舉個(gè)例子,比如日志功能,實(shí)現(xiàn)這個(gè)功能的代碼可能是很多類所需要的功能之一,但是如果我們在每一個(gè)類里都重復(fù)添加實(shí)現(xiàn)日志功能的代碼,將會有很多重復(fù)代碼。
上代碼(代碼參考https://blog.csdn.net/JinXYan/article/details/89302126

/**
 * @description: 業(yè)務(wù)類
 */
public class Calculator {

    public int add(int i, int j) {
        System.out.println("加法");
        return i + j;
    }

    public int sub(int i, int j) {
        System.out.println("減法");
        return i - j;
    }

    public int mul(int i, int j) {
        System.out.println("乘法");
        return i * j;
    }

    public int div(int i, int j) {
        System.out.println("除法");
        return i / j;
    }
}

通過切入點(diǎn),把業(yè)務(wù)類Calculator“橫向”切開,這樣很好的把業(yè)務(wù)類和日志類解耦。

/**
 * @description: 日志切面類,
 */
@Aspect
public class LogAspects {
    //切入點(diǎn)
    @Pointcut("execution(public int Calculator.*(..))")
    public void pointCut(){};

    //代表在目標(biāo)方法執(zhí)行前切入, 并指定在哪個(gè)方法前切入
    @Before("pointCut()")
    public void logStart(){
        System.out.println("@Before");
    }
    //代表在目標(biāo)方法運(yùn)行結(jié)束之后 ,不管有沒有異常
    @After("pointCut()")
    public void logEnd(){
        System.out.println("@After");
    }
    //代表在目標(biāo)方法正常返回值后運(yùn)行
    @AfterReturning("pointCut()")
    public void logReturn(){
        System.out.println("@AfterReturning");
    }
    //代表在目標(biāo)方法出現(xiàn)異常后運(yùn)行
    @AfterThrowing("pointCut()")
    public void logException(){
        System.out.println("@AfterThrowing");
    }
    //動(dòng)態(tài)代理,手動(dòng)執(zhí)行joinPoint.procced方法(程序執(zhí)行過程中明確的點(diǎn),一般指方法的調(diào)用)
    //簡單的來說就是,在目標(biāo)方法執(zhí)行之前是前置通知,在目標(biāo)方法執(zhí)行之后是后置通知
    @Around("pointCut()")
    public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("@Around:執(zhí)行目標(biāo)方法之前...");
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("@Around:執(zhí)行目標(biāo)方法之后...");
        return obj;
    }

}
/**
 * @description: 配置類
 */
@Configuration
@EnableAspectJAutoProxy
public class Config {
    @Bean
    public Calculator calculator(){
        return new Calculator();
    }

    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
}

測試一下

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
        Calculator c = app.getBean(Calculator.class);
        c.add(2, 3);
    }
}
運(yùn)行結(jié)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容