1. 程式人生 > 其它 >還不理解springAOP?來吧,帶你學習spring的面向切面程式設計(第一篇)

還不理解springAOP?來吧,帶你學習spring的面向切面程式設計(第一篇)

技術標籤:代理模式動態代理模式AOPspringaop面向切面程式設計

首先AOP是指面向切面程式設計,是OOP(面向物件程式設計)的補充。那麼什麼是切面(Aspect)呢,就是切點(pointcut)和通知(advice)的結合使用,什麼是通知?通知定義了切面要做什麼,在什麼時候做,而切點則定義了在什麼地方做,將兩者結合在一起就可以解釋切面是在何時何地做什麼功能。

舉一個例子,如果你要儲存一個賬戶資訊,但在執行儲存操作之前還想列印一條日誌,那控制日誌列印和儲存賬戶的資訊就構成了一個切面。列印日誌,在什麼時候列印就是通知,而在什麼地方執行儲存操作就是切點,這兩者構成了切面。

spring的AOP是基於動態代理實現的,為什麼這麼說呢,因為儲存賬戶和列印日誌兩個單獨的操作,需要AOP控制它們執行的時機。

案例如下:

介面:

package cn.com.lzxh.service;
/**
 * 業務層介面
 * spring的AOP是基於動態代理實現的。
 * */
public interface AccountService {

	void saveAccount();
}

實現類:

package cn.com.lzxh.service.impl;

import cn.com.lzxh.service.AccountService;

public class AccountServiceImpl implements AccountService {

	@Override
	public void saveAccount() {
		System.out.println("儲存資料。。。");
	}

}

日誌類:

package cn.com.lzxh.utils;

public class Logger {

	public void printLog() {
		System.out.println("在切入點方法執行之前,開始列印日誌。。。");
	}
}

spring配置檔案:

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
        
        <bean id="accountService" class="cn.com.lzxh.service.impl.AccountServiceImpl"></bean>
        
        <!-- 註冊日誌bean -->
        <bean id="logger" class="cn.com.lzxh.utils.Logger"></bean>
        
        <!-- 配置AOP -->
        <aop:config>
        	<!-- 配置切面 -->
        	<aop:aspect id="aspect" ref="logger">
        		<!-- 
        			before:代表前置通知,
        			method:代表通知所執行的方法
        			pointcut:代表切入點執行的方法
        		 -->
        		<aop:before method="printLog" pointcut="execution(public void cn.com.lzxh.service.impl.AccountServiceImpl.saveAccount())"/>
        	</aop:aspect>
        </aop:config>
        <!-- 加入以下配置,防止spring AOP代理混用導致異常 -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        
</beans>

在這裡需要注意,前置通知就是在切點方法執行的通知。

測試類:

package cn.com.lzxh.test;

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

import cn.com.lzxh.service.AccountService;
import cn.com.lzxh.service.impl.AccountServiceImpl;

public class TestAOP {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
		AccountService as = ac.getBean("accountService", AccountServiceImpl.class);
		as.saveAccount();
	}

}

執行結果:

以上就是一個完整的springAOP的例子。