代理模式
2021-05-06 本文已影响0人
金煜博
什么是代理模式?
一个对象被另一个对象进行代理,代理对象可以引用被代理对象,并且可以在被代理对象之前之后进行相关的操作,现实中俗称中介。
静态代理
每一个代理对象都需要手动完成创建
1.使用接口方式实现
通过引用被代理类调用代理类的方法
示例图

示例代码
1.创建抽象的行为接口
public interface Behavior {
void renting();
}
2.创建被代理类-房主
public class Homeowners implements Behavior {
@Override
public void renting() {
System.out.println("客户要租房");
}
}
3.创建代理类-中介
public class AgencyProxy implements Behavior {
private Homeowners renting;
public AgencyProxy(Homeowners renting) {
this.renting = renting;
}
@Override
public void renting() {
System.out.println("租房前看房源");
renting.renting();
System.out.println("租房后签合同");
}
}
4.创建客户类-启动类
public class Customer {
public static void main(String[] args) {
AgencyProxy agencyProxy = new AgencyProxy(new Homeowners());
agencyProxy.renting();
}
}
2.使用继承方式实现
修改代理类让代理类继承被代理类(t通过super关键字调用被代理方法)
public class AgencyProxy extends Homeowners {
private Homeowners renting;
@Override
public void renting() {
System.out.println("租房前看房源");
super.renting();
System.out.println("租房后签合同");
}
}
修改客户类- 启动类
public class Customer {
public static void main(String[] args) {
AgencyProxy agencyProxy = new AgencyProxy();
agencyProxy.renting();
}
}
运行结果

动态代理
通过java反射或字节码技术在运行时自动创建代理对象
jdk动态代理
实现InvocationHandler接口生成jdk动态代理类
示例代码
创建JdkInvocationHandler类
public class JdkInvocationHandler implements InvocationHandler {
//目标代理对象
private Object target;
public JdkInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("租房前看房源");
Object result = method.invoke(target, args);//通过java反射机制获取目标代理对象的方法
System.out.println("租房后签合同");
return result;
}
//使用jdk动态代理创建代理类
public <T> T getProxy(){
//1.目标对象 2.目标对象实现的接口 3.当前类
Object o = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
return (T) o;
}
}
修改客户类- 启动类
public class Customer {
public static void main(String[] args) {
//获取代理类
Behavior proxy = new JdkInvocationHandler(new Homeowners()).getProxy();
proxy.renting();
}
}
cglib动态代理
Cglib是代码生成类库。可以在运行时扩展java类与实现java接口,底层使用asm字节码可动态生成新的类。使用cglib动态代理可以生成被代理类的子类,子类重写父类非final修饰的方法,在子类的方法中对父类方法进行拦截。
示例代码
1.引入cglib包
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
</dependencies>
2.创建Cglib类
public class Cglib implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("租房前看房源");
Object res = methodProxy.invokeSuper(o, objects);
System.out.println("租房后签合同");
return res;
}
}
3.修改Customer类
Cglib cglib= new Cglib();
Enhancer enhancer = new Enhancer();
// 设置代理类的父类
enhancer.setSuperclass(Homeowners.class);
// 设置回调对象
enhancer.setCallback(cglib);
// 创建被代理对象
Homeowners homeowners = (Homeowners) enhancer.create();
homeowners.renting();