aop aspectj 實例

Spring AOP詳解

一.前言

    在以前的項目中,很少去關注spring aop的具體實現與理論,只是簡單瞭解了一下什麼是aop具體怎麼用,看到了一篇博文寫得還不錯,就轉載來學習一下,博文地址:http://www.cnblogs.com/xrq730/p/4919025.html

AOP

AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向對象編程)的補充和完善。OOP引入封裝、繼承、多態等概念來建立一種對象層次結構,用於模擬公共行爲的一個集合。不過OOP允許開發者定義縱向的關係,但並不適合定義橫向的關係,例如日誌功能。日誌代碼往往橫向地散佈在所有對象層次中,而與它對應的對象的核心功能毫無關係對於其他類型的代碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的代碼被稱爲橫切(cross cutting),在OOP設計中,它導致了大量代碼的重複,而不利於各個模塊的重用。

AOP技術恰恰相反,它利用一種稱爲"橫切"的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其命名爲"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重複代碼,降低模塊之間的耦合度,並有利於未來的可操作性和可維護性。

使用"橫切"技術,AOP把軟件系統分爲兩個部分:核心關注點橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在覈心關注點的多處,而各處基本相似,比如權限認證、日誌、事物。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

 

AOP核心概念

1、橫切關注點

對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之爲橫切關注點

2、切面(aspect)

類是對物體特徵的抽象,切面就是對橫切關注點的抽象

3、連接點(joinpoint)

被攔截到的點,因爲Spring只支持方法類型的連接點,所以在Spring中連接點指的就是被攔截到的方法,實際上連接點還可以是字段或者構造器

4、切入點(pointcut)

對連接點進行攔截的定義

5、通知(advice)

所謂通知指的就是指攔截到連接點之後要執行的代碼,通知分爲前置、後置、異常、最終、環繞通知五類

6、目標對象

代理的目標對象

7、織入(weave)

將切面應用到目標對象並導致代理對象創建的過程

8、引入(introduction)

在不修改代碼的前提下,引入可以在運行期爲類動態地添加一些方法或字段

 

Spring對AOP的支持

Spring中AOP代理由Spring的IOC容器負責生成、管理,其依賴關係也由IOC容器負責管理。因此,AOP代理可以直接使用容器中的其它bean實例作爲目標,這種關係可由IOC容器的依賴注入提供。Spring創建代理的規則爲:

1、默認使用Java動態代理來創建AOP代理,這樣就可以爲任何接口實例創建代理了

2、當需要代理的類不是代理接口的時候,Spring會切換爲使用CGLIB代理,也可強制使用CGLIB

AOP編程其實是很簡單的事情,縱觀AOP編程,程序員只需要參與三個部分:

1、定義普通業務組件

2、定義切入點,一個切入點可能橫切多個業務組件

3、定義增強處理,增強處理就是在AOP框架爲普通業務組件織入的處理動作

所以進行AOP編程的關鍵就是定義切入點和定義增強處理,一旦定義了合適的切入點和增強處理,AOP框架將自動生成AOP代理,即:代理對象的方法=增強處理+被代理對象的方法。

下面是代碼示例:

package AopTest;

public class Student {
  public String print(String msg) {
	System.out.println(msg);
	return "HelloWorld";
  }
}

package AopTest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import java.lang.Throwable;

@Aspect
public class StuInterceptor {
	/*
	 * 打印方法
	 * "*"表示返回值爲任意類型,printMsg爲執行的方法,".."表示參數爲任意類型
	 */
	@Pointcut("execution(* AopTest.Student.print(..))")
	public void printMethod() {
	}
	/*
	 * 前置通知
	 */
	@Before("printMethod()")
	public void printBeforeAdvice() {
		System.out.println("printBeforeAdvice()!");
	}
	/*
	 * 後置通知
	 */
	@AfterReturning(pointcut = "printMethod()",returning = "flag")
	public void printAfterAdvice(String flag) {
		System.out.println("printAfterAdvice()!" + flag);
	}
	
	@After("printMethod()")
	public void finallyAdvice() {
		System.out.println("fianllyAdvice()!");
	}
	/*
	 * args(name) 表示可以傳遞參數
	 */
	@Around("printMethod() && args(name)")
	public Object printAroundAdvice(ProceedingJoinPoint pjp,String name) throws Throwable {
		Object result = null;
		if (name.equals("whc")) {
			pjp.proceed();
		}else {
			System.out.println("printMsg 方法以及被攔截。。。");
		}
		
		return result;
	}
}
<?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"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       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">
    <context:annotation-config />
    <context:component-scan base-package="AopTest"/>
    <aop:aspectj-autoproxy />
    
    <bean id="stu" class="AopTest.Student"></bean>
    <bean id="stuInterceptor" class="AopTest.StuInterceptor"></bean>
</beans>

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

public class Main {
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/conf.xml");
		Student stu	= (Student)ctx.getBean("stu");
		stu.print("whc");

	}
}

注意需要使用AspectJ需要引入一些jar包:

aopalliance.jar

aspectjrt.jar

aspectjtools.jar

aspectjweaver.jar

org.aspectj.matcher.jar

可以根據需要引入上面的部分包,不一定全部需要引入,然後就可以編譯通過了,

如果還缺其他的包,可以百度查,然後下載下來就可以了。

資源下載地址:http://download.csdn.net/download/a1317338022/10130277


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章