天天看點

Spring AOP總結測試

AOP(Aspect Oriented Programming),即面向切面的程式設計。

(一)什麼是面向切面的程式設計

切面是指代碼中一些公共的非核心子產品的抽象,比如日志列印,可以将其從核心代碼中剝離出來,當程式運作需要時通過切面插入公共代碼即可,進而降低代碼的耦合度,提高代碼的可複用性,并使得我們程式設計的時候能夠更專注于核心業務代碼的編寫,這種程式設計模式叫做面向切面的程式設計。

類可以繼承,是以可以看做是有一個縱向的關系鍊,而切面可以橫向在多個類的方法中插入,是以也說是橫切面。Spring AOP中,切面出現的類通過IOC容器執行個體化并注入,進而将切面中的方法插入到核心業務代碼中。

(二)面向切面的程式設計的一些基本概念

  • 切面(aspect):代碼中的一些公共子產品的抽象,通常是一個類。
  • 連接配接點(joinpoint):可能插入切面的點。
  • 切入點(pointcut):(a predicate that matches join points)插入切面的連接配接點。
  • 通知(advice):也就是攔截到連接配接點之後,要執行的代碼,也即是要執行的切面類的方法。通知有以下幾種類型:
before advice:連接配接點之前執行。
after return advice:連接配接點正常傳回後執行
after throwing advice:連接配接點抛出異常後執行
after(final) advice:連接配接點正常傳回或者抛出異常後都會被執行的
around advice: 連接配接點前後都執行
           

這裡我們可以總結一下連接配接點(joinpoint)、切入點(pointcut)、通知(advice)之間的關系:通過切入點的描述找到連接配接點,在連接配接點插入相應類型的advice。

  • 目标對象:目标對象是要被攔截的對象,或者要被插入代碼的方法。
  • AOP代理對象:是目标對象和插入的切面對象融合之後的對象。一個 AOP 代理對象是一個 JDK 動态代理對象(基于接口)或 CGLIB 代理對象(基于類)。
  • 織入:切面和目标對象連接配接建立代理對象的過程。

(三)測試

接下來以一個執行個體說明,eclipse建立一個工程,工程視圖如下(截圖一部分),需要spring等相關jar包:

Spring AOP總結測試
Spring AOP總結測試

(1)核心業務接口和實作類

CoreService.java接口:

package com.spring.service;

public interface CoreService{
	
	public void coreMethod();
	
	public void coreBusiness();
}
           

(2)實作類

package com.spring.service;

public class ImpCoreService implements CoreService {
	public void coreMethod(){
		System.out.println("This is coreMethod");
	}
	
	public void coreBusiness(){
		System.out.println("This is coreBusiness");
	}

}
           

(3)切面類

package com.spring.aop;

public class Logger {
	public void aopLogBefore(){
		System.out.println("before");
	}
	
    public void aopLogAfter(){
    	System.out.println("after");
	}
}
           

(4)測試主類:

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

import com.spring.service.CoreService;

public class MainApp {

	public static void main(String[] args) {
		//建立Spring ApplicationContext 容器,利用配置檔案Beans.xml
		ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
		
		//容器注入ImpCoreService對象
		CoreService core = (CoreService)context.getBean("ImpCoreService");
		
		core.coreBusiness();
		System.out.println();
		core.coreMethod();
	}

}
           

(5)Beans.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-3.0.xsd
	http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!-- bean 是一個被執行個體化,組裝,并通過 Spring IoC 容器所管理的對象 -->
    <!-- id用于擷取對象使用 -->
	
	<bean id="ImpCoreService" class="com.spring.service.ImpCoreService">
	</bean>
	<bean id="Logger" class="com.spring.aop.Logger">
	</bean>

    <aop:config>
         <aop:aspect id="LoggerAspect" ref="Logger">
            <!--aop:pointcut 描述了連接配接點,通過這個描述可知,這裡連接配接點是CoreService接口中的所有方法,也可以改變描述隻連接配接一個方法-->
            <aop:pointcut id="TempPointcut" expression="execution(* com.spring.service.CoreService.*(..))" />
            
            <!--一個前置和後置的advice執行個體-->
            <aop:before method="aopLogBefore" pointcut-ref="TempPointcut" />
            <aop:after method="aopLogAfter" pointcut-ref="TempPointcut" />
         </aop:aspect>
     </aop:config>

</beans>
           

這裡通過XML配置檔案來實作AOP(也可以通過注解),執行結果如下,可以看到切面對象插入到了目标對象中。或者說advice代碼插入到了業務代碼中。

Spring AOP總結測試