Spring架構第五篇之Spring與AOP,spring第五篇aop
一、AOP概述
AOP(Aspect Orient Programming),面向切面編程,是物件導向編程OOP的一種補充。物件導向編程是從靜態角度考慮程式的結構,而面向切面編程是從動態角度考慮程式運行過程。
AOP底層就是採用動態代理模式實現的,採用了兩種代理:JDK的動態代理與CGLIB的動態代理。
面向切面編程,就是將交叉商務邏輯封裝成切面,利用AOP容器的功能將切面織入到主商務邏輯中。所謂交叉商務邏輯是指,通用的、與主商務邏輯無關的代碼。如安全檢查、事務、日誌等。
若不是用AOP,則會出現代碼糾纏,即交叉商務邏輯與主商務邏輯混合在一起,這樣會使主商務邏輯變的混雜不清。
二、通知Advice1、通知詳解(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的實現