Java静态代理与动态代理
1.静态代理(通过接口实现类去代理另一个接口实现类)
- 解释:静态代理就比如租房这个事件,房东是真实对象,中介是代理对象,我是客户,我要去找中介才能租房子(比自己找更方便,还有中介服务)。房东实现租房接口能出租房子,中介实现租房接口也能出租房子,但是房子是房东的,中介只能代理,于是中介只能靠房东(真实对象)实现出租房子,当然中介还可以加上其它自己想要的操作
- 例子:
租房接口:
package com.lxf.demo01;
//租房接口
public interface Rent {
public void rent();
}
房东(真实对象):
package com.lxf.demo01;
//房东对象
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
中介(代理对象)
package com.lxf.demo01;
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
//将真实对象赋给host
public setHost(Host host) {
this.host = host;
}
@Override
public void rent() {
//看房子
seeHouse();
//签合同
singContract();
//出租房子
host.rent();
//收费
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//收中介费
public void fare(){
System.out.println("中介收中介费");
}
//签合同
public void singContract(){
System.out.println("签租赁合同");
}
}
客户(测试实例):
package com.lxf.demo01;
public class Client {
public static void main(String[] args) {
//房东:真实对象
Host host=new Host();
//代理:代理对象
Proxy proxy = new Proxy();
//将真实对象传给代理对象
proxy.setHost(Host host);
//找中介租房(中介在中间捞油水)
proxy.rent();
}
}
2.动态代理
-
动态代理分类:
- 基于接口:jdk动态代理类
- 基于类:cglib动态代理类
- java字节码实现:javassist(用在JBoss服务器上)
2.1、jdk动态代理类
解释:再次看租房这个事件,房东是真实对象,中介是代理对象,我是客户,我要去找中介才能租房子。房东实现租房接口能出租房子,此时中介不实现租房接口,建一个生成代理类的类(通过set或者构造函数接收真实对象,生成代理类),生成代理类的类实现InvocationHandler接口,然后将房东丢入生成代理类的类生成中介代理类,这个于是中介代理类就可以出租房子了,当然中介还可以加上其它自己想要的操作
租房接口:
package com.lxf.demo01;
//租房接口
public interface Rent {
public void rent();
}
房东接口:
package com.lxf.demo01;
//房东对象
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
生成代理类的类:
package com.lxf.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//实现代理类生成的类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的真实对象
private Rent rent;
//设置真实对象
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理类
public Object getProxy(){
//Proxy.newProxyInstance(ClassLoader loader,Class<?>[] Ingterfaces,InvocationHandler h);
//第一个参数:真实对象的类加载器
//第二个参数:真实对象实现的所有的接口
//第三个参数: 执行处理器,放的一个实现了invocationHandler接口的对象(也就是本类)。
return Proxy.newProxyInstance(rent.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质:使用反射机制实现!
//实现方法
Object result = method.invoke(rent, args);
return result;
}
}
客户(测试实例):
package com.lxf.demo03;
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//获取代理角色的类
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//将真实角色加入
handler.setRent(host);
//代理角色
Rent proxy = (Rent) handler.getProxy();
//实现方法
proxy.rent();
}
}
2.2、CGLIB动态代理类
一、它是什么?
- Code Generation Library:代码生成库
- 底层使用的是ASM,ASM是一个Java字节码操纵框架(小而快)
- ASM可以直接生成二进制class文件
- ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类(动态代理类)
二、特点
- CGLib动态代理不要求委托类需要实现接口,没有接口照样能实现代理业务
- CGLib动态代理能够实现基于方法级别的拦截处理
- CGLib动态代理执行方法,不是使用反射执行Method.invoke()
- 针对同一个委托类中的不同方法可以使用不同的拦截逻辑来进行处理。结合调用链还可以实现多重代理。
三、使用细节
- MethodIntercepor:顾名思义就是可以针对委托类的方法执行前后做拦截处理的类,甚至可以不去执行委托类的真实方法逻辑,直接自定义返回。
- 通过Enhancer获取代理对象
四、代码演示
3.静态代理与动态代理异同
-
相同处:都是通过代理对象去实现方法,并且都可以加上其它操作。
-
不同处:静态代理是通过代理对象实现类去代理真实对象实现类,而动态代理是通过一个生成代理类的类去生成代理对象,动态代理的好处在于"很灵活"。静态代理的代理对象是一个实际的类,要是真实对象发生改变,代理对象也要改。而动态代理的代理对象通过类产生,而不完全依赖于类,当真实对象发生改变也没事,甚至可以将生成代理类的类改成万能类:

本文深入解析Java中的静态代理与动态代理,包括静态代理通过接口实现类代理另一接口实现类的原理,以及动态代理中JDK动态代理类和CGLIB动态代理类的运作机制。通过租房场景生动阐述了代理模式的应用。

被折叠的 条评论
为什么被折叠?



