静态代理和动态代理

代理模式:

静态代理:类如结婚,我们需要找婚庆公司,而婚庆公司就是代理类,而我们需要结婚的人为被代理类,而结婚就是我们以及婚庆公司共同实现的一个目标。

用代码进行模拟。

首先要有一个接口,类如我们取一个Marry(结婚)作为该接口。


public interface Marry {
	public void toMarry();
}

然后我们再去实现Marry接口的类,命名为You(你),这也是被代理的类

public class You implements Marry{

	@Override
	public void toMarry() {
		// TODO Auto-generated method stub
		System.out.println("你要结婚");
	}

}

在定义一个代理类,命名Marrycompany(婚庆公司),这也是代理类

public class Marrycompany  implements Marry{
	private Marry marry;
	
	public Marrycompany(Marry marry) {
		super();
		this.marry = marry;
	}

	@Override
	public void toMarry() {
		// TODO Auto-generated method stub
		System.out.println("1111");
		
		marry.toMarry();
		System.out.println("222");
	}
	
}

然后我们在定义一个类,命名start,用来运行代码,实现静态代理。

public class Start {
	public static void main(String[] args) {
		Marry youMarry=new You();
		Marrycompany marryompany=new Marrycompany(youMarry);
		
		marryompany.toMarry();
	}
}

结果:

1111
你要结婚
222

静态代理是已知代理的类型,可以通过扩展代理类,进行功能的附加和增加,例如Marrycompany类中的toMarry方法写的。

动态代理:当我们不知道被代理的类型时,我们无法写相应的代理类,这时就可以使用动态代理,动态代理分为jdk动态代理及CGlib动态代理。

首先我们先来讲一下jdk动态代理:

直接看代码,讲解在代码下面:

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

public class JdkProxy {
	//目标对象
	private Object target;
	
	public JdkProxy(Object target) {
		this.target=target;
	}
	
	//得到代理方法
	public Object getProcy() {
		
		//类加载器
		ClassLoader loader=this.getClass().getClassLoader();
		//得到代理对象接口
		Class[] interfaces=target.getClass().getInterfaces();
		InvocationHandler invocationHandler=new InvocationHandler() {
           /**
        * proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0
        * method:我们所要调用某个对象真实的方法的Method对象
        * args:指代代理对象方法传递的参数
            */
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// TODO Auto-generated method stub
                System.out.println("11111");
				Object result=method.invoke(target, args);
				//return 的是方法的返回值
				return result;
			}
		};
		
		Object object=Proxy.newProxyInstance(loader, interfaces, invocationHandler);
		return object;
	}
}

这次我们动态生成代理类,所以我们需要首先定义一个Object类,由于我们并不知道被代理的类,需要传入并被Object target对象获取(定义一个构造方法),在生成代理类的方法中,需要返回一个Object类型参数,这也是因为我们不知道传入的target是何类型。在方法中我们首先先得到类加载器,类加载器将会作为参数为我们生成代理类,然后我们需要得到代理对象接口,通过传入的target,然后我们还需要一个InvocationHandler的参数,InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法,在invoke方法中调用method.invoke便是调用代理对象中的方法,它需要一个Object返回值,return的是代理对象的返回值如果没有可以写null,在Object result=method.invoke(target, args);这代码上下可以实现代理对象功能的附加,我们再写一个start方法用来运行一下:

import java.lang.reflect.Proxy;

import com.lyt.statics.Marry;
import com.lyt.statics.You;

public class start {
	public static void main(String[] args) {
		//目标对象
		Marry you=new You();
		//得到代理对象
		JdkProxy jdkProxy=new JdkProxy(you);
		Marry object=(Marry) jdkProxy.getProcy();
		//代理对象调用方法
		object.toMarry();
		
	}
}

运行结果:

11111
你要结婚

CGlib动态代理:我们直接看一下生成代理类的代码块:

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{
	private Object target;
	
	public CglibProxy(Object target) {
		super();
		this.target = target;
	}

	public Object getProxy() {
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(target.getClass());
		MethodInterceptor methodInterceptor=new MethodInterceptor() {
			
			@Override
			public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
				// TODO Auto-generated method stub
				System.out.println("cglib...");
				return null;
			}
		};
		enhancer.setCallback(methodInterceptor);
		return enhancer.create();
		
	}
}

测试代码:

import com.lyt.statics.Marry;
import com.lyt.statics.You;

public class CglibyTest {
	public static void main(String[] args) {
		Marry target=new You();
		CglibProxy cglibProxy=new CglibProxy(target);
		Marry proxy=(Marry) cglibProxy.getProxy();
		proxy.toMarry();
	}
}

cglib与jdk动态代理相似,但是cglib用在没有接口的代理对象,使用继承的方法来实现代理类的实现,而jdk是通过接口,这是两个的区别。

总结:

代理模式实现分类以及对应区别
静态代理:手动为目标对象制作代理对象,即在程序编译阶段完成代理对象的创建。

动态代理:在程序运行期动态创建目标对象对应代理对象。
 jdk 动态代理:被代理目标对象 必须实现某一或某一组接口实现方式通过回调创建代理对象。
 cglib 动态代理:被代理目标对象可以不必实现接口,继承的方式实现。
动态代理相比较静态代理,提高开发效率,可以批量化创建代理,提高代码复用率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值