Spring 的AOP--spring框架動態實現AOP

   springAOP代理由springIOC容器負責生成,管理,其依賴管理也由IOC容器負責管理,因此,AOP代理可以直接使用容器總的其他bean實例作爲目標,這種管理可由IOC容器的依賴注入提供。spring默認使用java動態代理來創建AOP 代理,這樣就可以爲任何接口實例創建代理了。

   spring也可以使用cglib的動態代理,關於jdk動態代理和cglib動態代理之間的區別和聯繫,請看小編《細說java動態代理和cglib動態代理》,當我們配置了cglib之後,在需要代理類而不是代理某個接口的時候,spring框架會自動切換爲cglib。但是默認上使用jdk的動態代理,如果需要我們可以通過配置文件,強制使用cglib代理。

   通過上篇博客《Spring的AOP-AspectJ 的靜態實現》,我們不難發現,要實現AOP,程序員主要需要下面的操作:

        *   定義普通的業務組件

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

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

    重點操作在於後兩步,所以AOP的代理工作可以整合爲下列的公式:

               AOP代理的方法 = 增強處理 + 目標對象的方法

  spring實現AOP主要有兩種方式:

 1.  基於註解的“零配置”方式

     這裏的註解主要是指@Before……,@aspect ;具體操作請繼續看:

   ✎  啓動對AspectJ的支持

<span style="font-family:SimSun;font-size:18px;"><aop:aspectj-autoproxy/></span>

  ✎  定義切面bean

    當啓動了AspectJ的支持後,我們只需要在spring容器中配置一個帶@Aspect註解的Bean,spring將會自動識別該Bean,並將該Bean作爲切面處理:

<span style="font-family:SimSun;font-size:18px;">package com.ysc.spring;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


@Aspect
public class SecurityHandler {
	// 這裏是該類中的內容

}</span>

   使用@aspect註解標註一個java類,該java類將會作爲切面bean。而負責自動增強的後處理Bean將會略過該bean,不會對該bean進行任何增強處理;當spring容器檢測到某個bean類使用了@aspect註解的修飾之後,spring容器不會對該bean進行增強,所以無需擔心該bean類會被增強處理;

   ✎  Before的增強處理

      PS:增強處理有多種方式,這裏以Before的增強處理爲例:

<span style="font-family:SimSun;font-size:18px;">@Before("adAddMethod()")
//@After("adAddMethod()")
private void checkSecurity(){
	System.out.println("-----------checkSecurity----------");
}</span>

   我們對checkSecurity()方法進行Before的增強處理,而被增強的java方法是adAddMethod,這就意味着該add方法將被進行 執行前 檢查安全性的增強處理,我們編寫一個client.java 的類,執行對UserManager的方法的調用,查看 當前的Add方法被添加增強處理之後的效果:

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		UserManager userManager = (UserManager)factory.getBean("userManager");
		userManager.findUserById(1);
		userManager.modifyUser(1, "lisi", "123");
		
		userManager.addUser("張三", "123");
	
		
	}

}

   查看執行結果如下:

-------------userManager.findUserById()---------
-------------userManager.modifyUser()---------
-----------checkSecurity----------
-------------userManager.add()---------
   發現只有被添加增強處理的add方法被執行了安全性檢查的方法,且在add方法執行之前執行的安全檢查,所以使用Before增強處理只能在目標方法執行之前織入增強,而after同理,只能在目標方法執行之後織入增強;

 2.基於xml配置文件的管理方式

  ✎ 配置切面

<span style="font-family:SimSun;font-size:18px;"><aop:config>
	<aop:aspect id="" ref="">
		……
	</aop:aspect>
</aop:config></span>

  ✎ 配置增強處理

<span style="font-family:SimSun;font-size:18px;">package com.ysc.spring;

import org.aspectj.lang.JoinPoint;


public class SecurityHandler {
	
	private void checkSecurity(JoinPoint joinpoint){
		for(int i =0;i<joinpoint.getArgs().length;i++){
			System.out.println(joinpoint.getArgs()[i]);
		}
		
		System.out.println(joinpoint.getSignature().getName());
		
		System.out.println("-----------checkSecurity----------");
	}

}</span>

  ✎ 配置切入點

<span style="font-family:SimSun;font-size:18px;"><aop:pointcut expression="execution(* add*(..))" id="addAddMethod"/></span>

    這時, 編譯Client.java 類,依舊可以實現零配置方式的效果,所以不管是零配置的方式還是基於xml的方式,都可以在spring框架的基礎上實現AOP。

   當我們理解並清晰了Spring的AOP實現原理之後,發現它其實並不神祕,希望能幫到你更好的理解AOP這個“神祕”的切面編程理念!!

        

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