1. 程式人生 > >Spring框架第五篇之Spring與AOP

Spring框架第五篇之Spring與AOP

lease nco 列表 odi 動態 www implement .get org

一、AOP概述

AOP(Aspect Orient Programming),面向切面編程,是面向對象編程OOP的一種補充。面向對象編程是從靜態角度考慮程序的結構,而面向切面編程是從動態角度考慮程序運行過程。

AOP底層就是采用動態代理模式實現的,采用了兩種代理:JDK的動態代理與CGLIB的動態代理。

面向切面編程,就是將交叉業務邏輯封裝成切面,利用AOP容器的功能將切面織入到主業務邏輯中。所謂交叉業務邏輯是指,通用的、與主業務邏輯無關的代碼。如安全檢查、事務、日誌等。

若不是用AOP,則會出現代碼糾纏,即交叉業務邏輯與主業務邏輯混合在一起,這樣會使主業務邏輯變的混雜不清。

二、通知Advice

1、通知詳解

(1)前置通知MethodBeforeAdvice

定義前置通知,需要實現MethodBeforeAdvice接口。該接口中有一個方法before(),會在目標方法執行之前執行。

前置通知的特點:

1、在目標方法執行之前執行。

2、不改變目標方法的執行流程,前置通知代碼不能阻止目標方法執行。

3、不改變目標方法執行的結果。

舉例:

創建IService接口:

package com.ietree.spring.basic.aop.beforeadvice;

public interface IService {

    void doFirst();

    void
doSecond(); }

創建接口的實現類:

package com.ietree.spring.basic.aop.beforeadvice;

public class SomeServiceImpl implements IService {

    @Override
    public void doFirst() {
        System.out.println("執行doFirst()方法");
    }

    @Override
    public void doSecond() {
        System.out.println("執行doFirst()方法");
    }

}

創建前置通知類MyMethodBeforeAdvice,該類必須實現MethodBeforeAdvice接口:

package com.ietree.spring.basic.aop.beforeadvice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 前置通知
 * 
 * @author Root
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

    // 當前方法在目標方法執行之前執行
    // method:目標方法
    // args:目標方法參數列表
    // target:目標對象
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        // 對於目標方法的增強代碼就寫在這裏
        System.out.println("執行前置通知...");
    }

}

配置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"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- 1、註冊目標對象 -->
    <bean id="someService" class="com.ietree.spring.basic.aop.beforeadvice.SomeServiceImpl"/>
    
    <!-- 2、註冊切面:通知 -->
    <bean id="myAdvice" class="com.ietree.spring.basic.aop.beforeadvice.MyMethodBeforeAdvice"/>
    
    <!-- 3、生成代理對象 -->
    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 指定目標對象 -->
        <!-- <property name="targetName" value="someService"/> -->
        <property name="target" ref="someService"/>
        <!-- 指定切面 -->
        <property name="interceptorNames" value="myAdvice"/>
    </bean>
    
</beans>

測試:

package com.ietree.spring.basic.aop.beforeadvice;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    @Test
    public void test() {
        
        String resource = "com/ietree/spring/basic/aop/beforeadvice/applicationContext.xml";
        
        ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
    
        IService service = (IService)ac.getBean("serviceProxy");
        
        service.doFirst();
        System.out.println("==============");
        service.doSecond();
    }

}

輸出:

執行前置通知...
執行doFirst()方法
==============
執行前置通知...
執行doFirst()方法

註意:執行之前需要導入spring-aop-4.3.9.RELEASE.jar包

(2)後置通知AfterReturningAdvice

(3)環繞通知MethodInterceptor

(4)異常通知ThrowsAdvice

三、顧問Advisor

四、自動代理生成器

五、AspectJ對AOP的實現

Spring框架第五篇之Spring與AOP