利用动态代理实现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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章