0
点赞
收藏
分享

微信扫一扫

AOP 动态代理


Spring AOP使用两种代理机制:基于JDK的动态代理;基于CGLIB的动态代理。之所以需要两种,是因为JDK本身只提供接口的代理,不支持类的代理。



JDK动态代理:java.lang.reflect包下的Proxy, InvocationHandler



1.编写一个handler类实现InvocationHandler接口,invoke方法:



public Object invoke(Object target, Method method, Object[] args) throws Throwable {
 
 
 

   //代理前逻辑
 
 
 

   Object obj = methos.invoke(target, args);
 
 
 

   //代理后逻辑
 
 
 

   return obj;
 
 
 

   }



2.调用Proxy,



Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);//三个参数classLoader, interfaces, 实现invocationHandler的类



GCLib动态代理:JDK的限制:只能为接口创建代理实例.



CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截技术拦截所有父类方法的调用,并顺势织入横切逻辑。



1、创建一个CGLibProxy实现MethodInterceptor



package com.billkang;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();
	
	public Object getProxy(Class clazz) {
		enhancer.setSuperclass(clazz); //设置需要创建子类的类
		enhancer.setCallback(this);
		return enhancer.create(); //通过字节码技术动态创建子类实例
	}
	
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("代理前逻辑");
		Object result = proxy.invokeSuper(obj, args);
		System.out.println("代理后逻辑");
		return result;
	}
}



ForumServiceImpl) cgLibProxy.getProxy(ForumServcieImpl.class);



由于CGlib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final、private方法进行代理。



对于singleton的代理,推荐使用CGlib,对于其他作用域的代理,最好使用JDK,因为CGlib创建代理的时候慢,而创建出的代理对象运动效率极高,而使用JDK代理的表现刚好相反。



举报

相关推荐

0 条评论