利用動態代理實現AOP的簡單示例(JDK和cglib分別實現)

公司組織的內部培訓,裏面留了一個思考作業:基於AOP的統一日誌處理

要求實現一個AOP的技術雛形,能夠實現方法的調用前、正常執行後、異常執行後以及執行後的日誌輸出;同時要求,對於Java API對象和Object的方法做攔截。

我使用了兩種方法來實現

1、利用JDK自帶的reflect包。

2、利用cglib包實現。

工程目錄:

Dao接口定義:

public interface DAO {
	public void create();
	public void query();
	public void  update();
	public void delete();
}
DAOImp實現

public class DAOImp implements DAO {

	@Override
	public void create() {
		// TODO Auto-generated method stub
		System.out.println("create is called!");
	}

	@Override
	public void query() {
		// TODO Auto-generated method stub
		System.out.println("query is called!");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("update is called!");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("delete is called!");
	}

}

使用JDK產生動態代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DAOProxyUsingJDK implements InvocationHandler {
	private Object proxy;
	public Object bind(Object proxy){
		this.proxy = proxy;
		return Proxy.newProxyInstance(this.proxy.getClass().getClassLoader(), 
				this.proxy.getClass().getInterfaces(),this);
	}
	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		// TODO Auto-generated method stub
		Object result = null;  
        System.out.println("事務開始");  
        //執行方法  
        result=arg1.invoke(proxy, arg2);  
        System.out.println("事務結束");
		return null;
	}
}

使用cglib來實現
import java.lang.reflect.Method;

import org.logicalcobwebs.cglib.proxy.Enhancer;
import org.logicalcobwebs.cglib.proxy.MethodInterceptor;
import org.logicalcobwebs.cglib.proxy.MethodProxy;

public class DAOProxyUsingCglib implements MethodInterceptor{
	private Object target;
	public Object getInstance(Object target) {  
	        this.target = target;  
	        Enhancer enhancer = new Enhancer();  
	        enhancer.setSuperclass(this.target.getClass());  
	        // 回調方法  
	        enhancer.setCallback(this);  
	        // 創建代理對象  
	        return enhancer.create();  
	    }  
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		String method = arg1.getName();
		if ("create".equals(method)){
			System.out.println("create事務開始");
			arg3.invokeSuper(arg0, arg2);
			System.out.println("create事務結束");
		}else
			if("query".equals(method)){
				System.out.println("query事務開始");
				arg3.invokeSuper(arg0, arg2);
				System.out.println("query事務結束");
			}
			else
				if ("update".equals(method)){
					System.out.println("update事務開始");
					arg3.invokeSuper(arg0, arg2);
					System.out.println("update事務結束");
				}
				else 
					if ("delete".equals(method)){
						System.out.println("delete事務開始");
						arg3.invokeSuper(arg0, arg2);
						System.out.println("delete事務結束");
					}		
		return null;
	}
}


DAOProxyUsingCglib.java還實現了對與不同方法的攔截。

測試類

import DAO.DAO;
import DAOImpl.DAOImp;
import DynamicProxy.DAOProxyUsingCglib;
import DynamicProxy.DAOProxyUsingJDK;


public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		DAOProxyUsingJDK proxy = new DAOProxyUsingJDK();
//		DAO dao = (DAO)proxy.bind(new DAOImp());
//		dao.create();
		DAOProxyUsingCglib proxy = new DAOProxyUsingCglib();
		DAO dao = (DAO) proxy.getInstance(new DAOImp());
		dao.create();
		dao.query();
		dao.update();
		dao.delete();
	}

}

運行結果:


改進的地方:

需要增加對與異常的處理

類似於Cglib簡單學習(1)

例子實現權限控制


發佈了125 篇原創文章 · 獲贊 50 · 訪問量 112萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章