1. 程式人生 > >JavaEE--spring-AOP介紹及spring基於XML的AOP配置

JavaEE--spring-AOP介紹及spring基於XML的AOP配置

AOP即面向切面程式設計技術,AOP能夠剖開封裝的物件內部,並將那些影響了多個類並且與具體業務無關的公共行為封裝成一個獨立的模組。在執行時通過動態代理技術或者是在程式編譯期間進行靜態的"織入"方式。

用大白話來說:就是我們把程式中重複的程式碼抽取出來,在它需要被執行的時候,通過動態代理的技術,在執行期間不修改原始碼的基礎上對已經存在的方法進行增強.

AOP的優點:
1.減少重複程式碼
2.提高開發效率

3.方便維護

AOP使用的技術: 動態代理.
Spring如何實現動態代理(兩種代理方式):

在Spring中框架會根據目標類是否實現了介面來決定採用哪種代理方式. 
若目標物件實現了若干介面,spring使用JDK的java.lang.reflect.Proxy類代理。 
優點:因為有介面,所以使系統更加鬆耦合 
缺點:為每一個目標類建立介面
若目標物件沒有實現任何介面,spring使用CGLIB庫生成目標物件的子類。 
優點:因為代理類與目標類是繼承關係,所以不需要有介面的存在。 
缺點:因為沒有使用介面,所以系統的耦合性沒有使用JDK的動態代理好。

AOP在Spring中最常用在什麼地方? 

事務的控制.因為增刪改這些操作都需要一些固定操作.如:開啟事務,提交事務,... 我們可以把這些操作封裝起來,當執行增刪改的時候 進行動態增強,自動加上事務的程式碼.

AOP相關術語.

JoinPoint 連線點:
指的是那些被連線的方法,因為Spring只支援方法型別的連線點.

PointCut  切入點:
指的是我們對那些JoinPoint進行攔截的定義.

Advice 通知/增強:
指的是攔截到JoinPoint之後要做的事情.
通知有五種:前置通知,後置通知,異常通知,最終通知,環繞通知.

Introduction 引介:
是通知的一種特殊型別,可以在執行期間為類動態的新增一些方法或Field

Target 目標物件:
代理的目標物件.

Weaving 織入:
指把增強應用到目標物件來建立新的物件的過程.

Proxy 代理:
一個類被AOP織入增強後,就產生了一個結果代理類.

Aspect 切面:

指切入點和通知(引介)的結合.

下面我們來測試一下Spring基於xml的AOP配置(在業務方法執行前執行日誌方法).

1.建立工程

2.匯入jar包(除了Spring的,還有AOP的).


3.建立業務層程式碼(沒有業務邏輯,只是測試是否可以增強)

public interface CustomerSerice {
	//儲存客戶
	public void saveCustomer();
	//修改客戶
	public void updateCustomer();

}
public class CustomerServiceImpl implements CustomerSerice {
	@Override
	public void saveCustomer() {
		System.out.println("呼叫持久層儲存使用者");
	}
	@Override
	public void updateCustomer() {
		System.out.println("呼叫持久層修改使用者");
	}
}

4.建立配置檔案ApplicationContext.xml

引入約束,配置業務層資源交Spring管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	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-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<bean id="customerService" class="service.CustomerServiceImpl"/>
</beans>

5.建立通知類(增強類)

public class Logger {
	public void beforePrintLog() {
		System.out.println("列印日誌操作開始執行");
	}

}

6.在xml中配置通知類.

<bean id="logger" class="util.Logger"/>

7.在xml中配置AOP

<aop:config>
	<!-- 配置切入點表示式 切入點就是要進行增強的位置 -->
	<!-- 全匹配方式 -->
	<aop:pointcut expression="execution(public void service.CustomerServiceImpl.*())" id="pt"/>
	<!-- 省略方式 -->
	<!-- <aop:pointcut expression="execution(* *.*.*(**))" id="pt1"/> -->
	<!-- 配置切面 id:切面id ref:引用的通知類id -->
	<aop:aspect id="logAdvice" ref="logger">
	<!-- 配置前置通知  method:指定通知類中用於增強的方法 pointcut-ref:指定切入點表示式的引用-->
	<aop:before method="beforePrintLog" pointcut-ref="pt"/>
	</aop:aspect>
</aop:config>

8.建立測試類

public class Test {
	public static void main(String[] args) {
		//獲取Spring容器
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//獲取service物件
		CustomerSerice customerSerice = (CustomerSerice) ac.getBean("customerSerice");
		customerSerice.saveCustomer();
		customerSerice.updateCustomer();
	}
}

9.測試


可以看出,我們在測試方法中只執行了service方法,但是service方法執行前均執行了日誌列印方法,說明我們的配置生效.Spring的AOP動態為我們執行了增強.

喜歡的朋友請點個贊哦~~