1. 程式人生 > >Spring框架(二)————AOP使用擴充套件

Spring框架(二)————AOP使用擴充套件

一.AOP 1.簡介;AOP(Aspect Oriented Programming 面向切面程式設計),可以通過預編譯方式和執行期動態代理實現在不修改原始碼的情況下給程式動態統一新增功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是呼叫者和被呼叫者之間的解耦,提高程式碼的靈活性和可擴充套件性,提高程式的可重用性,同時提高了開發的效率。 AOP可以說也是這種目標的一種實現。AOP是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果

常用於日誌記錄,效能統計,安全控制,事務處理,異常處理等等。

2.作用:將重複性的程式碼抽取出來,放在專門的類和方法中,便於管理和維護

3.面向切面程式設計AOP的基本概念: (1)切面(Aspect): 一個模組化的橫切邏輯,可能會橫切多個物件。 (2)連線點(Join Point): 程式執行中的某個具體執行點。 (3)增強處理(Advice): 切面在某個特定連線點上執行的程式碼邏輯 (4)切入點(Pointcut): 對連線點的特徵進行描述,可以使用正則表示式。增強處理和一個切入點表示式相關聯,並在與這個切入點匹配的某個連線點上執行。 (5)目標物件(Target object):被一個或多個切面增強的物件。 (6)AOP代理(AOP proxy):由AOP框架所建立的物件,實現執行增強處理方法等功能。 (7)織入(Weaving):將增強處理連線到應用程式中的型別或物件上的過程。 (8)增強處理型別:前置增強,後置增強,環繞增強,異常丟擲異常,最終增強等。 前置通知(Before):在目標方法被呼叫之前呼叫通知功能。 後置通知(After):在目標方法完成之後呼叫通知,此時不會關心方法的輸出是什麼。 返回通知(After-returning):在目標方法成功執行之後呼叫通知。 異常通知(After-throwing):在目標方法丟擲異常後呼叫通知。 環繞通知(Around):通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為。

4.AOP的例項

關於前置增強,後置增強,後置增強帶返回值,後置增強帶異常的程式碼如下: (1).實體類Target

public class Target {

    public String show(String name) throws Exception {
        System.out.println("這是目標方法...");
        if (1/0==1){
            throw new Exception("除數不能為0");
        }
        return "hello"+name;
    }
}

(2).增強類AdviceTarget

import org.aspectj.lang.JoinPoint;
import java.util.logging.Logger;

public class AdviceTarget {
    private static final Logger log=Logger.getLogger(String.valueOf(AdviceTarget.class));
    //前置增強
    public void before(JoinPoint point){
        System.out.println("目標物件:"+point.getTarget()+"方法名:"+point.getSignature().getName()+
                "方法入參"+ point.getArgs());
        }
    //後置增強
    public void after(JoinPoint point){
        System.out.println("後置增強");
    }
    //後置增強帶返回值
    public void afterReturn(JoinPoint point,Object value){
        System.out.println("後置帶返回值:"+value);
    }
    //後置增強帶異常
    public void afterException(JoinPoint point,Exception ex){
        System.out.println("後置帶異常:"+ex);
    }
 }

(3).建立spring配置檔案:spring_aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"
       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">

    <bean id="target" class="com.bdqn.aop.Target"/>
    <bean id="adviceTarget" class="com.bdqn.aop.AdviceTarget"/>
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(public String show(String))"/>
        <aop:aspect ref="adviceTarget">
            <!--前置增強-->
            <aop:before method="before" pointcut-ref="pointcut"/>
            <!--後置增強-->
            <aop:after method="after" pointcut-ref="pointcut"/>
            <!--後置增強帶返回值-->
            <aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="value"/>
            <!--後置增強帶異常-->
            <aop:after-throwing method="afterException" pointcut-ref="pointcut" throwing="ex"/>
        </aop:aspect>
    </aop:config>

</beans>

(4).編寫測試類

import com.bdqn.aop.Target;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Junit {
   
    @Test
    public void testAop(){
        ApplicationContext context=new ClassPathXmlApplicationContext("spring_aop.xml");
        Target target=(Target)context.getBean("target");

        try {
            target.show("張三");
        } catch (Exception e) {
            System.out.println("除數不能為0");
        }
    }
}

執行結果如下圖: 在這裡插入圖片描述

關於環繞增強的程式碼 (1).實體類Target

public class Target {

    public String show(String name) throws Exception {
        System.out.println("這是目標方法...");
        return "hello"+name;
    }
}

(2).增強類AdviceTarget

 //環繞增強
    public void around(ProceedingJoinPoint point){
        String str=(String)point.getArgs()[0];
        if (str.equals("admin")){
            //有許可權,可以訪問目標方法
            try {
                String value=point.proceed().toString();
                System.out.println("返回值"+value);
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }else {
            System.out.println("無許可權訪問");
        }
    }

(3).建立spring配置檔案:spring_aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <bean id="target" class="com.bdqn.aop.Target"/>
    <bean id="adviceTarget" class="com.bdqn.aop.AdviceTarget"/>
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(public String show(String))"/>
        <aop:aspect ref="adviceTarget">
         
            <!--環繞增強-->
            <aop:around method="around" pointcut-ref="pointcut" />
        </aop:aspect>
    </aop:config>
    
</beans>

(4).測試類

 @Test
    public void testAop(){
        ApplicationContext context=new ClassPathXmlApplicationContext("spring_aop.xml");
        Target target=(Target)context.getBean("target");
        try {
            target.show("admin");
        } catch (Exception e) {
            System.out.println("除數不能為0");
        }
    }

執行結果:返回值admin