1. 程式人生 > 實用技巧 >7、AOP程式設計思想

7、AOP程式設計思想

AOP (Aspect Oriented Programming)

1.1、什麼是AOP

  AOP意為面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。

  AOP是0OP的延續,是軟體開發中的一個熱點,也是Spring框架中的一一個重要內容,是函數語言程式設計的一種衍生範型。

  利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

1.2、AOP在Spring中的作用

提供宣告式事務;允許使用者自定義切面

  • 橫切關注點:跨越應用程式多個模組的方法或功能。即是,與我們業務邏輯無關的,但是我們需要關注的部分,就是橫切關注點。如日誌,安全,快取,事務等等
  • 切面(ASPECT) :橫切關注點被模組化的特殊物件。即,它是一個類。
  • 通知(Advice) :切面必須要完成的工作。即,它是類中的一個方法。
  • 目標(Target) :被通知物件。
  • 代理(Proxy) :向目標物件應用通知之後建立的物件。
  • 切入點(PointCut) :切面通知執行的"地點”的定義。
  • 連線點(JointPoint) :與切入點匹配的執行點。

2、使用Spring實現AOP的第一種方式:

【maven匯入AOP依賴包】

    <!--springAOP的包-->
        <dependency>
            <groupId
>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>

【xml配置檔案中匯入aop的約束】

<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd ">

1、service業務層

public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}

2、業務層的實現類

public class UserServiceImpl implements UserService {

    public void add() {
        System.out.println("新增使用者的方法~");
    }

    public void delete() {
        System.out.println("刪除使用者的方法~");
    }

    public void update() {
        System.out.println("修改使用者的方法~");
    }

    public void select() {
        System.out.println("查詢使用者的方法~");
    }
}

3、日誌類,在方法前後切入

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;

// 日誌增強類,方法前的通知
public class Log implements MethodBeforeAdvice {
    /**
     * @param method 要執行的目標物件的方法
     * @param args   引數
     * @param target 目標物件
     */
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("執行了" + target.getClass().getName() + "物件的" + method.getName() + "方法");
    }
}
package com.zhixi.Log;

import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
// 日誌增強類,方法執行後,返回值
public class AfterLog implements AfterReturningAdvice {

    /**
     * ,如果有的話*被呼叫方法的@param方法* @param將方法的引數args * @param以方法呼叫的目標為目標也許
     *
     * @param returnValue 方法返回的值
     * @param method      要執行的目標的方法
     * @param args        引數
     * @param target      目標物件
     */
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("執行" + method.getName() + "返回" + returnValue);
    }
}

4、配置檔案

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd

        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd

">
    <bean id="userServiceImpl" class="com.zhixi.service.UserServiceImpl"/>
    <bean id="log" class="com.zhixi.Log.Log"/>
    <bean id="afterLog" class="com.zhixi.Log.AfterLog"/>

    <!--配置aop:先匯入aop的約束-->
    <aop:config>
        <!--pointcut:切入點,expression表示式:()-->
        <aop:pointcut id="pointcut" expression="execution(* com.zhixi.service.UserServiceImpl.*(..))"/>

        <!--執行環繞增加-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"></aop:advisor>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>
</beans>

5、測試類以及結果:

import com.zhixi.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 動態代理代理的是介面
        UserService userServiceImpl = (UserService) context.getBean("userServiceImpl");
        userServiceImpl.add();
    }
}
執行了com.zhixi.service.UserServiceImpl物件的add方法
新增使用者的方法~
執行add返回null