常用代理模式理解与操作
一、什么是代理设计模式
1.解决特定问题的一套代码
- 优点:
①保护真实对象
②让真实对象职责更加明确
③扩展(在不动原代码下提供新功能) - 比喻:
①真实对象–>幕后主人
②代理对象–>秘书(帮主人做事)
③抽象对象–>功能(相当于事情)
二、静态代理模式
1 什么是静态代理:
- 由代理对象代理真实对象的所有功能
- 需自己编写代理类
- 每个代理功能需要单独编写
2 缺点:
- 当代理功能比较多时,代理类中的方法也需要很多
3 代码演示
-
真实对象类
- 代理对象
- 代理对象
三、JDK动态代理
1 JDK动态代理和cglib动态代理相比较
- 优点:jdk自带,不需要提供第三方jar
- 缺点:真实对象必须实现接口
利用反射机制原理,效率不高
2.代码示例
- 真实类
package com.xq.jdkproxy;
public class LaoZong implements gongneng {
public void eat() {
System.out.println("老总吃饭!");
}
public void target() {
System.out.println("老总制定目标!");
}
}
- 委托类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MiShu implements InvocationHandler {
private LaoZong lz=new LaoZong();
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("预约时间!");
Object result = method.invoke(lz, args);
System.out.println("记录访客!");
return result;
}
}
- 测试类
import java.lang.reflect.Proxy;
public class Me {
public static void main(String[] args) {
MiShu ms=new MiShu();
//类加载器是单例 测试结果为true
System.out.println(Me.class.getClassLoader()==LaoZong.class.getClassLoader());
/**
* 第一个参数:为反射时需要的类加载器
* 第二个参数:是要实现的功能接口
* 第三个参数:委托类
*/
gongneng gn = (gongneng) Proxy.newProxyInstance(Me.class.getClassLoader(), new Class[]{gongneng.class}, ms);
gn.eat();
}
}
四、cglib动态代理
1.优点:
- 基于字节码生成真实类的子类–>运行效率高于jdk动态管理
- 不需要实现接口
2.maven项目需要导入的依赖:
<!-- cglib依赖 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<!-- 字节码解析助手 -->
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.0</version>
</dependency>
3.代码示例
- 真实类
public class LaoZongC {
public void eat(){
System.out.println("吃饭");
}
}
- 委托类
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MiShuC implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("预约时间!");
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("记录访客!");
return result;
}
}
- 测试类
import net.sf.cglib.proxy.Enhancer;
public class Me {
public static void main(String[] args) {
Enhancer eh=new Enhancer();
//设置代理的真正对象
eh.setSuperclass(LaoZongC.class);
//设置委托类
eh.setCallback(new MiShuC());
//获取代理类
LaoZongC lz = (LaoZongC) eh.create();
lz.eat();
}
}