程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Spring進階之路(10)-Advice簡介以及通過cglib生成AOP代理對象

Spring進階之路(10)-Advice簡介以及通過cglib生成AOP代理對象

編輯:JAVA綜合教程

Spring進階之路(10)-Advice簡介以及通過cglib生成AOP代理對象


Advice簡介

1. Before:在目標方法執行之前執行織入,如果Before的處理中沒有進行特殊的處理,那麼目標方法最終會執行,但是如果想要阻止目標方法執行時,可以通過拋出一個異常來實現,Before處理無法拿到目標方法的返回值,因為這時候目標方法並未運行。

2. AfterReturning: 返回之後執行(前提是目標方法執行成功),可以訪問到目標對象的返回值,但是不可以改變返回值。

3. AfterThrowing:拋出異常之後執行,可以對異常進行適當的修復或者將異常輸出到日志中。

4. After:不管目標對象執行成功與否都會被織入常用於釋放資源等。

5. Around:既可以在目標方法之前,又可以在目標方法調用之後執行,但是需要在線程安全的情況下執行,如果需要目標方法執行之前或者之後共享某種數據,應該考慮用Around。需要改變返回值的時候,只能使用Around。

通過cglib生成AOP代理對象

上一篇文章中已經提到,通過JDK的代理生成AOP代理對象的方式,但是前提是目標方法實現了接口,如果沒有實現接口的話,那麼怎麼辦?

在這種情況下,我們使用cglib來實現生成AOP代理對象。

定義一個沒有實現接口的User類。

package com.siti.spring20160315;

public class User {

	private String userName;
	private String password;
	
	public User(){}
	
	public User(String userName, String password) {
		super();
		this.userName = userName;
		this.password = password;
	}
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	public void saySth() {
		System.out.println("hello!");
	}
}
對於Spring而言,如果說目標類實現了接口的話,會按照JDK代理生成AOP代理對象,如果沒有實現接口的話,那麼會使用cglib來生成AOP代理對象。
package com.siti.spring20160315;

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;


public class MyProxy4AOPObject implements InvocationHandler{

	private Object targetObj;
	
	public Object getProxyObject(Object targetObj){
		this.targetObj = targetObj;
		
		Enhancer enhance = new Enhancer();
		// 將目標類設置為代理對象的父類,產生目標類的子類,這個子類覆蓋所有父類的非final修飾的方法
		enhance.setSuperclass(this.targetObj.getClass());
		// 設置回調,可以單獨建立一個類實現InvocationHandler接口實現裡面的invoke方法
		enhance.setCallback(this);
		
		return enhance.create();
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		User user = (User)this.targetObj;
		Object result = null;
		try{
			// 攔截,符合要求的才允許運行
			if(user.getUserName() != null && user.getUserName() != ""){
				// -->Before
				result = method.invoke(this.targetObj, args);
				// -->AfterReturning
			}
		}catch (Exception e) {
			// -->AfterThrowing
		}finally{
			// -->After
		}
		
		return result;
	}

}

package com.siti.spring20160315;

public class MainTest {

	public static void main(String[] args) {
		User user = new User("wy", "wy");
		MyProxy4AOPObject myProxy4AOPObject = new MyProxy4AOPObject();
		User us = (User) myProxy4AOPObject.getProxyObject(user);
		us.saySth();
	}
}
這裡會輸出:hello!

如果將User中name屬性賦值為null或者""的話就不會輸出,因為在invoke方法中進行了限制,調用的目標對象的方法不會執行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved