笨鸟之AOP的JDKProxy和CGlibProxy动态代理的模拟及比较

通常对于spring的AOP功能,大家都能说出一二来,但是AOP技术到底是怎么实现的呢?

分为jdk自动的动态代理方式和cglib实现动态代理这两种方式,那下面就来具体看看怎么实现的。

一,看看jdk的动态代理方式:

1,用到jdk动态代理的时候,目标类(HcieServiceImpl)必须有实现接口(HcieService)。

package cn.china.hu;

public class HcieServiceImpl implements HcieService { //必须实现接口
	
	private String user;
	
    public HcieServiceImpl(String str) {	
		this.user = str;
	}

	@Override
	public void save(String str) {
		System.out.println("save()..."+str);
	}
	public String getUser() {
		return user;
	}
	public void setUser(String user) {
		this.user = user;
	}

}

2,  动态代理类必须实现InvocationHandler这个接口,并实现invoke()方法。

      有一个创建代理实例的方法createProxyInstance(),Proxy实例化方法的参数必须有类加载器和实现的接口。

package cn.china.hu;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * JDK的Proxy实现AOP的功能
 */
public class JDKProxyFactory implements InvocationHandler{
	
	private Object target;
	
	public Object createProxyInstance(Object target){
		
		this.target = target;
		
		//create proxy
		Object obj = Proxy.newProxyInstance(
				this.target.getClass().getClassLoader(), //目标类加载器
				this.target.getClass().getInterfaces(), //目标类实现的接口
				this
			);
		return obj;	
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		//环绕通知
		HcieServiceImpl hcie = (HcieServiceImpl) this.target;
		Object result = null;
		if (hcie.getUser() != null) {
			try {
				//前置通知 ...advice
				System.out.println("前置通知");
				
				result = method.invoke(target, args);
				//后置通知
			} catch (Exception e) {
				// 例外通知
			}finally{
				//最终通知
				System.out.println("最终通知");
			}
		}
		return result;
	}

	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
}

二,看看cglib实现动态代理方式:

1,用到cglib实现动态代理的时候,目标类(HcieServiceImpl2)没有实现接口。

package cn.china.hu;

public class HcieServiceImpl2 { //用cglib处理没有实现接口的
	
	private String user;
	
	public HcieServiceImpl2() {} //空参的构造函数,在cglib中superClass的时候需要用到
	
                     public HcieServiceImpl2(String str) {//带惨的构造函数	
		this.user = str;
	}

	public void save(String str) {
		System.out.println("save方法..."+str);
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

}

2,动态代理类必须实现MethodInterceptor这个接口,并实现intercept()方法。

      有一个创建代理实例的方法creaProxyInstace(),Enhancer对象来创建代理对象。

package cn.china.hu;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * 用cglib的方式实现AOP的功能
 */
public class CGlibProxyFactory implements MethodInterceptor {
	
	private Object target;
	
	//create proxy
	public Object creaProxyInstace(Object target){
		this.target = target;
		Enhancer enhancer = new Enhancer();  //用到这个Enhancer对象,jdk中用的Proxy对象
		enhancer.setSuperclass(target.getClass());
		enhancer.setCallback(this);
		
		return enhancer.create();
	}

	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		//环绕通知
		HcieServiceImpl2 hcie = (HcieServiceImpl2) this.target;
		Object result = null;
		if (hcie.getUser() != null) {
			try {
				//前置通知 ...advice
				System.out.println("前置通知");
				
				result = method.invoke(target, args);
				//后置通知
			} catch (Exception e) {
				// 例外通知
			}finally{
				//最终通知
				System.out.println("最终通知");
			}
		}
		return result;		
	}

	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
	
}


三,测试类:

public class AOPtest {

	@Test
	public void test() {
		//JDKProxyFactory
		JDKProxyFactory proxy = new JDKProxyFactory();
		HcieService service = (HcieService)proxy.createProxyInstance(new HcieServiceImpl("a"));
		service.save("b");
		
		//CGlibProxyFactory
		CGlibProxyFactory cgliab= new CGlibProxyFactory();
		HcieServiceImpl2 lib = (HcieServiceImpl2) cgliab.creaProxyInstace(new HcieServiceImpl2("aaa"));
		lib.save("bbb");
	}
}


四,两者的对比到此为止吧,后续有时间再多补充补充,共同学习!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值