AOP和spring下的兩種簡單用法

概念解釋

  AOP (Aspect Orentied Programming , 面向方面編程)

  面向方面的編程需要把程序邏輯分解成不同的部分稱爲所謂的關注點。跨一個應用程序的多個點的功能被稱爲橫切關注點,這些橫切關注點在概念上獨立於應用程序的業務邏輯

  程序在運行時,動態的將代碼切入到類的指定方法或者說指定位置上

  舉例來說,我有個程序,裏面有三個應用,訪問前都需要登陸,藉助於AOP,我可以動態的將登陸模塊加到訪問方法執行前。像登陸這種的可重用的模塊化單元叫做切面(aspect)

  有各種各樣的常見的很好的方面的例子,如日誌記錄、審計、聲明式事務、安全性和緩存等

名詞解釋

  • 連接點(Join Point)

  程序運行中的一個點,是切點的候選點,是能夠插入切面的點

  • 通知(Advice)

  指一個連接點在特定的切面要做的事情

  • 切點(Pointcut)

  切點就是從連接點中選出的,用來插入切面的點,在代碼中,定義 pointcut 的下一步就是定義 aspect 並且插入合適的位置

<aop:config>
    <aop:pointcut id="cutAspetc" expression="execution(* example.Play.play())"/>
    <aop:aspect id="cutAspetc" ref="cut">
        <aop:before method="before" pointcut-ref="cutAspetc"/>
        <aop:after method="after" pointcut-ref="cutAspetc"/>
    </aop:aspect>
</aop:config>

這是stackoverflow裏的高票解釋

Joinpoint: A joinpoint is a candidate point in the Program Execution of the application where an aspect can be plugged in. This point could be a method being called, an exception being thrown, or even a field being modified. These are the points where your aspect’s code can be inserted into the normal flow of your application to add new behavior.

Advice: This is an object which includes API invocations to the system wide concerns representing the action to perform at a joinpoint specified by a point.

Pointcut: A pointcut defines at what joinpoints, the associated Advice should be applied. Advice can be applied at any joinpoint supported by the AOP framework. Of course, you don’t want to apply all of your aspects at all of the possible joinpoints. Pointcuts allow you to specify where you want your advice to be applied. Often you specify these pointcuts using explicit class and method names or through regular expressions that define matching class and method name patterns. Some AOP frameworks allow you to create dynamic pointcuts that determine whether to apply advice based on runtime decisions, such as the value of method parameters.

  • 目標對象(Target Object)

  被一個或者多個切面通知的對象,也就是需要被 AOP 進行攔截對方法進行增強(使用通知)的對象,也稱爲被通知的對象。

  • 切面(Aspect)

  它是一個跨越多個類的模塊化的關注點,它是通知和切點合起來的抽象,它定義了一個切點用來匹配連接點,也就是需要對需要攔截的那些方法進行定義;它定義了一系列的通知用來對攔截到的方法進行增強

  • 織入(Weaving)

  是將切面應用到目標對象的過程

Spring AOP編程

準備工作

​ spring的幾個jar包自然是必不可少

​ 我用idea直接創建的spring項目,但是仍然缺了幾個包,導致試了幾種方法都一直報錯,分別是

  • aspectjrt.jar

  • aspectjweaver.jar

  • aspectj.jar

    實現功能,在play()方法執行前後各打印一句話

基於註解的AOP實現

連接點
package example;

import org.springframework.stereotype.Component;

@Component
public class Play {
    public void play() {
        System.out.println("play");
    }
}
切面
package example;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class CutPoint {
    @Before("execution(* example.Play.play())")
    public void before() {
        System.out.println("before");
    }

    @After("execution(* example.Play.play())")
    public void after() {
        System.out.println("after");
    }
}
配置文件
<?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-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="example" />

    <aop:aspectj-autoproxy/>

</beans>
入口函數
package example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Play play = (Play) context.getBean("play");
        play.play();
    }
}
結果
before
play
after

用配置文件實現AOP

連接點
package example;
public class Play {
    public void play() {
        System.out.println("play");
    }
}
切面
package example;
public class CutPoint {
    public void before() {
        System.out.println("before");
    }

    public void after() {
        System.out.println("after");
    }
}
配置文件
<?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-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <bean id="play" class="example.Play"/>
    <bean id="cut" class="example.CutPoint"/>
    <aop:config>
        <aop:pointcut id="cutAspetc" expression="execution(* example.Play.play())"/>
        <aop:aspect id="cutAspetc" ref="cut">
            <aop:before method="before" pointcut-ref="cutAspetc"/>
            <aop:after method="after" pointcut-ref="cutAspetc"/>
        </aop:aspect>
    </aop:config>

</beans>
入口函數
package example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Play play = (Play) context.getBean("play");
        play.play();
    }
}
結果
before
play
after
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章