代理设计模式(静态代理、JDK动态代理、Cglib动态代理)

代理设计模式是一种常用的设计模式,属于结构型模式的一种。代理对象通过持有真实对象来达到访问真实对象的功能,从而保护真实对象,并且可以扩展真实对象的功能。代理设计模式一般有三种:静态代理、JDK动态代理和Cglib动态代理。

静态代理

静态代理中,真实对象和代理对象需要实现同一个接口。

接口类:

package com.test.staticproxy;

public interface FunctionInterface {
	void function();
}

真实对象类:

package com.test.staticproxy;

public class RealFunctionProvider implements FunctionInterface {

	@Override
	public void function() {
		System.out.println("RealFunctionProvider -> function() ");
	}

}

代理对象类:

package com.test.staticproxy;

public class ProxyFunctionProvider implements FunctionInterface {
	
	private RealFunctionProvider realObject;
	
	public ProxyFunctionProvider(RealFunctionProvider realObject) {
		this.realObject = realObject;
	}

	@Override
	public void function() {
		System.out.println("ProxyFunctionProvider -> function()");
		realObject.function();
	}

}

测试类:

package com.test.staticproxy;

public class Test {

	public static void main(String[] args) {
		RealFunctionProvider realObject = new RealFunctionProvider();
		ProxyFunctionProvider proxyObject = new ProxyFunctionProvider(realObject);
		proxyObject.function();
	}

}

执行结果:
在这里插入图片描述

JDK动态代理

在JDK中的java.lang.reflect包下有一个InvocationHandler接口,是JDK动态代理需要实现的接口。JDK动态代理是通过反射机制,动态生成接口的实例来代理真实对象。

接口类:

package com.test.jdkdynamicproxy;

public interface FunctionInterface {
	void function();
}

真实对象类:

package com.test.jdkdynamicproxy;

public class RealFunctionProvider implements FunctionInterface {

	@Override
	public void function() {
		System.out.println("RealFunctionProvider -> function()");
		
	}

}

代理对象类:

package com.test.jdkdynamicproxy;

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

public class DynamicProxyFunctionProvider implements InvocationHandler {
	
	RealFunctionProvider realObject;
	
	public DynamicProxyFunctionProvider(RealFunctionProvider realObject) {
		this.realObject = realObject;
	}

	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
		System.out.println("DynamicProxyFunctionProvider -> invoke");
		arg1.invoke(realObject, arg2);
		return realObject;
	}

}

代理类需要实现InvocationHandler 接口和invoke方法,invoke方法中有三个参数分别是:代理对象、调用的接口方法的 Method 实例和代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。

在invoke方法体中,应该通过arg1.invoke(realObject, arg2);传入真实对象和方法参数。

测试类:

package com.test.jdkdynamicproxy;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) {
		
		RealFunctionProvider realObject = new RealFunctionProvider();
		DynamicProxyFunctionProvider proxyObject = new DynamicProxyFunctionProvider(realObject);
		ClassLoader classLoader = realObject.getClass().getClassLoader();
		FunctionInterface fun = (FunctionInterface) Proxy.newProxyInstance(classLoader, 
				new  Class[]{FunctionInterface.class}, proxyObject);
		fun.function();
	}

}

运行结果:
在这里插入图片描述

Cglib动态代理

实现Cglib动态代理需要引入Cglib的jar包和依赖包:

在这里插入图片描述

使用Cglib实现动态时,真实对象类不需要实现接口,代理类需要实现Cglib中的MethodInterceptor接口。在运行过程会创建真实对象的子类来实现代理。

真实对象类:

package com.test;

public class RealFunctionProvider {
	
	public void function() {
		System.out.println("RealFunctionProvider -> function");
	}

}

代理类:

package com.test;

import java.lang.reflect.Method;

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

public class CglibDynamicProxyFunctionProvider implements MethodInterceptor{

	
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		System.out.println("CglibDynamicProxyFunctionProvider -> intercept");

		Object result = arg3.invokeSuper(arg0, arg2);
		return result;
	}

}

测试类:

package com.test;

import net.sf.cglib.proxy.Enhancer;

public class Test {
	public static void main(String[] args) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(RealFunctionProvider.class);
		enhancer.setCallback(new CglibDynamicProxyFunctionProvider());
		
		RealFunctionProvider realObject = (RealFunctionProvider) enhancer.create();
		realObject.function();
		
	}
}

运行结果:

在这里插入图片描述

Cglib是基于字节码操作的,不需要通过反射,执行效率要高于JDK动态代理;不需要实现接口,在执行的过程中会生成真实对象的子类来代理。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值