代理机制原理及实操

代理的作用:代码扩展,也就是方法的增强;让你可以在不用修改源码的情况下,增强一些方法

静态代理:
代理类由程序员创建的然后编译成.class文件。但是其中缺点是,具有重复代码,灵活性不好,例如在执行接口A中所有方法之前加上日志逻辑,那么使用静态代理的话,在代理类中每个方法都得加上

动态代理:
是在运行的时候,通过jvm中的反射进行动态创建对象,生成字节码对象(构造方法参数 InvocationHandler h类型),传入由我们实现InvocationHandler接口的对象,通过反射创建代理对象。 然后当调用代理对象的任何方法都会调用h中的 invoke(Object proxy,Method method,Object[] args)传入当前代理对象、当前调用的方法、方法参数值。

动态代理的优势是实现无侵入式的代码扩展,也就是方法的增强;让你可以在不用修改源码的情况下,增强一些方法;在方法的前后你可以做你任何想做的事情(甚至不去执行这个方法就可以)。

动态代理分两种:

jdk方式的代理是对类的接口以及接口的对象进行代理

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.sun.org.apache.bcel.internal.generic.NEW;

public class DirectJDKProxy {
//	对接口以及接口对象进行代理
	
	
	public static Object getProxy(Object  object) {
		Class<?>  klass=object.getClass();
//		获取类加载器
		ClassLoader  classLoader=klass.getClassLoader();
//		获取类的接口	
		Class<?> [] interfaces=klass.getInterfaces();
		
//		返回代理对象
		return  Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("进行前置拦截");
				Object  result=method.invoke(object, args);
				System.out.println("进行后置拦截");
				System.out.println("进行了jdk代理");
				return result;
			}
		});
		
		}

}


核心:
Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
}
• proxy => 这个参数指定动态生成的代理类,这里是
• method => 这个参数表示传入接口中的所有Method对象
• args => 这个参数对应当前method方法中的参数

Cglib方式的代理 需要jar包

package proxy;

import java.lang.reflect.Method;

import org.omg.CORBA.PUBLIC_MEMBER;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.sun.org.apache.bcel.internal.generic.RETURN;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy {
	private static Object object;

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}

	public CglibProxy() {
		
	}
	
	private static  Object  innerProxy(Object object) {
		Class<?> parentclass=object.getClass();
		Enhancer  enhancer=new Enhancer();
		enhancer.setSuperclass(parentclass);
//		回调函数  指向函数的指针
		enhancer.setCallback(new MethodInterceptor() {
			@Override
			public Object intercept(Object proxy, Method method, Object[] arg2, MethodProxy methodProxy) throws Throwable {
				System.out.println(proxy.getClass());
				System.out.println(proxy instanceof SomeClass);
				System.out.println("进行前置拦截");
				Object result=method.invoke(object, arg2);
				System.out.println("进行后置拦截");
				System.out.println();
				return result;
			}
			
		});
		return enhancer.create();	
		}
	public static Object  getProxy() {
		
		if (object==null) {
			return null;
		}
		return 	innerProxy(object);
		
	}
	
	public static Object  getProxy(Class<?> klass) {
		Object object;
		if(klass!=null) {
			try {
				object=klass.newInstance();
				return innerProxy(object);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
}

核心:
enhancer.setSuperclass(parentclass);
// 回调函数 指向函数的指针
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] arg2, MethodProxy methodProxy)

给出测试类

package proxy;

public class SomeClass implements ISomeClass{

	public SomeClass() {
		
	}

	@Override
	public String DealString(String str) {
		str="["+str+"]";
		System.out.println(str);
		return str;
	}

package proxy;

Test  测试:

public class Test {

	public Test() {
	}

	public static void main(String[] args) {
		SomeClass  someClass=new SomeClass();
		ISomeClass someclassProxy=(ISomeClass) DirectJDKProxy.getProxy(someClass);
		someclassProxy.DealString("快来代理我呀");
	
		CglibProxy  cProxy=new CglibProxy();
		SomeClass  sClass=(SomeClass) cProxy.getProxy(SomeClass.class);
		sClass.DealString("快来代理我呀");

动态代理的应用:RPC框架,Spring AOP机制,进行日志的书写

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值