天天看點

Srping AOP面向切面程式設計

AOP:中文名稱面向切面程式設計 (Aspect Oriented Programming)

正常程式執行流程都是縱向執行流程

 面向切面程式設計,在原有縱向執行流程中添加橫切面

 不需要修改原有程式代碼   高擴充性    原有功能相當于釋放了部分邏輯.讓職責更加明确

Srping AOP面向切面程式設計

面向切面程式設計是什麼?

在程式原有縱向執行流程中,針對某一個或某一些方法添加通 知,形成橫切面過程就叫做面向切面程式設計.

常用概念 

 原有功能: 切點, pointcut

 前置通知: 在切點之前執行的功能. before advice

 後置通知: 在切點之後執行的功能,after advice

 如果切點執行過程中出現異常,會觸發異常通知.throws advice

 所有功能總稱叫做切面.

 織入: 把切面嵌入到原有功能的過程叫做織入

開始 導入jar包

Srping AOP面向切面程式設計
Srping AOP面向切面程式設計

編寫切入點

public class Myadvice {

    public void mybefore(){
        System.out.println("前置" );
    }
    public void myafterReturing(){
        System.out.println("傳回後置");
    }
    public void myafter(){
        System.out.println("後置");
    }
    public void mythrow(){
        System.out.println("異常");
    }

    public Object myarround(ProceedingJoinPoint p) throws Throwable{
        System.out.println("環繞-前置");
        Object result = p.proceed();
        System.out.println("環繞後置");
        return result;
    }
}
           

功能類

public class Demo {

    public void demo(){
        System.out.println("demo運作了。");
    }
}
           

spring配置檔案

<!--配置demo類-->
    <bean id="demo" class="com.xt.aop.Demo"></bean>

    <!-- 切面類-->
    <bean id="myAdvice" class="com.xt.aop.Myadvice"></bean>

    <!-- 配置切入點 -->
    <aop:config>
        <!-- 切入點-->
        <aop:pointcut id="myPoint" expression="execution(* com.xt.aop.Demo.*(..) )"></aop:pointcut>

        <aop:aspect ref="myAdvice">
            <!--前置通知-->
            <aop:before method="mybefore" pointcut-ref="myPoint"></aop:before>
            <!-- 後置通知-->
            <aop:after method="myafter" pointcut-ref="myPoint"/>
            <!-- 傳回後通知 -->
            <aop:after-returning method="myafterReturing" pointcut-ref="myPoint"/>
            <!-- 異常通知 -->
            <aop:after-throwing method="mythrow" pointcut-ref="myPoint"/>
            <!-- -環繞通知 -->
            <aop:around method="myarround" pointcut-ref="myPoint"/>
        </aop:aspect>
    </aop:config>
           

execution 是切入點表達式,表示要在哪個類中哪個方法中進行切入,可以跟随自己項目進行配置

出自官方文檔:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
            throws-pattern?)

modifiers-pattern 表示攔截方法的通路修飾符
ret-type-pattern  傳回類型
declaring-type-pattern 攔截方法所在類
name-pattern(param-pattern) 攔截方法(以及方法參數清單)
throws-pattern    方法異常
           

運作效果如下

Srping AOP面向切面程式設計

Spring生成代理對象的過程

1.建立容器對象時,根據切入點表達式攔截的類,生成代理對象

2.如果目标對象有實作接口,使用JDK代理

3.如果目标對象沒有實作接口,使用CGLIB代理

4.從容器中擷取代理後的對象

5.執行代理對象的方法,在運作時,動态植入切面類中的通知方法

二、基于注解實作AOP程式設計

功能類

@Component("demo")//加入到IOC容器
public class Demo implements DemoI {

    public void demo(){
        System.out.println("demo運作了。");
    }
}
           

切面類

@Component//加入IOC容器
@Aspect//指定為切面類
public class Myadvice {
    //辨別切入點
    @Pointcut("execution(* com.xt.aopano.aop.Demo.*(..))")
    public void point(){}
    

    //@Before("execution(* com.xt.aopano.aop.Demo.*(..))")
    @Before("point()")
    public void mybefore(){
        System.out.println("前置" );
    }

    @AfterReturning("execution (* com.xt.aopano.aop.Demo.*(..) )")
    public void myafterReturing(){
        System.out.println("傳回後置");
    }

    @After("execution(* com.xt.aopano.aop.Demo.*(..) )")
    public void myafter(){
        System.out.println("後置");
    }

    @AfterThrowing("execution(* com.xt.aopano.aop.Demo.*(..) )")
    public void mythrow(){
        System.out.println("異常");
    }

    @Around("execution(* com.xt.aopano.aop.Demo.*(..) )")
    public Object myarround(ProceedingJoinPoint p) throws Throwable{
        System.out.println("環繞-前置");
        Object result = p.proceed();//執行目标方法
        System.out.println("環繞後置");
        return result;
    }
}
           

spring配置檔案

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 開啟注解掃描 -->
    <context:component-scan base-package="com.xt.aopano.aop"></context:component-scan>
    <!-- 開啟aop注解 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>