1. 静态代理模式
1.1 解释
所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网上连接、存储器中的大对象、文件或其它昂贵或无法复制的资源。
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
1.2 组成
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
1.3 UML
1.4 GiveGift 接口类
/**
* @Author: czn
* 送礼物接口
* @Date 2020/11/18 22:17
*/
public interface GiveGift {
void giveDolls();
void giveFlowers();
void giveChoolate();
}
1.5 SchoolGirl 被追求者
/**
* @Author: czn
* 被追求者
* @Date 2020/11/18 22:19
*/
public class SchoolGirl {
String name;
public SchoolGirl(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1.6 Pursuit 追求者 委托类
/**
/**
* @Author: czn
* 追求者
* @Date 2020/11/18 22:18
*/
public class Pursuit implements GiveGift {
SchoolGirl mm;
public Pursuit(SchoolGirl mm) {
this.mm = mm;
}
public void giveDolls() {
System.out.println(mm.name+"送你洋娃娃");
}
public void giveFlowers() {
System.out.println(mm.name+"送你鲜花");
}
public void giveChoolate() {
System.out.println(mm.name+"送你巧克力");
}
}
1.7 Proxy 代理送礼物类
/**
* @Author: czn
* 代理送礼物类
* @Date 2020/11/18 22:22
*/
public class Proxy implements GiveGift {
Pursuit gg;
public Proxy(SchoolGirl mm) {
this.gg = new Pursuit(mm);
}
public void giveDolls() {
gg.giveDolls();
}
public void giveFlowers() {
gg.giveFlowers();
}
public void giveChoolate() {
gg.giveChoolate();
}
}
1.7 Client
/**
* @Author: czn
* @Date 2020/11/18 22:24
*/
public class Client {
public static void main(String[] args) {
SchoolGirl mm = new SchoolGirl("娇娇");
proxy.Proxy proxy = new proxy.Proxy(mm);
proxy.giveFlowers();
proxy.giveChoolate();
proxy.giveDolls();
}
}
1.8 结果
娇娇送你鲜花
娇娇送你巧克力
娇娇送你洋娃娃
2 jdk动态代理(jdk基于接口)
2.1 DynamicProxyHandler实现jdk里面的InvocationHandler 接口
/**
* @Author: czn
* @Date 2020/11/18 22:47
*/
public class DynamicProxyHandler implements InvocationHandler {
//代理类中的真实对象
private Object object;
//传递真实对象
public DynamicProxyHandler(Object object) {
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理之前可以做一些操作,也就是对目标类进行增强
Object result = method.invoke(object,args);
//代理之前可以做一些操作,也就是对目标类进行增强
return result;
}
}
2.2 Client
/**
* @Author: czn
* @Date 2020/11/18 22:24
*/
public class Client {
public static void main(String[] args) {
SchoolGirl mm = new SchoolGirl("娇娇");
System.out.println("--------jdk动态代理--------");
GiveGift pursuit = new Pursuit(mm);
/**
* 代理:
* 间接。
* 获取代理对象:
* 要求:
* 被代理类最少实现一个接口
* 创建的方式
* Proxy.newProxyInstance(三个参数)
* 参数含义:
* ClassLoader:和被代理对象使用相同的类加载器。
* Interfaces:和被代理对象具有相同的行为。实现相同的接口。
* InvocationHandler:如何代理。
*
*/
GiveGift giveGift = (GiveGift)Proxy.newProxyInstance(
GiveGift.class.getClassLoader(),
new Class[]{GiveGift.class},
new DynamicProxyHandler(pursuit));
giveGift.giveFlowers();
giveGift.giveChoolate();
giveGift.giveDolls();
}
}
2.3 结果
--------jdk动态代理--------
娇娇送你鲜花
娇娇送你巧克力
娇娇送你洋娃娃
3 cglib动态代理
3.1 代理类
/**
* @Author: czn
* @Date 2020/11/19 17:34
*/
public class cglibProxy implements MethodInterceptor {
//目标类
Object object;
public cglibProxy(Object object) {
this.object = object;
}
/**
*
* @param method 目标类的方法反射
* @param objects 方法动态入参
* @param proxy 代理类实例
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
//代理之前可以做一些操作,也就是对目标类进行增强
Object result = proxy.invoke(object,objects);
//代理之后可以做一些操作,也就是对目标类进行增强
return result;
}
}
3.2 Cient
/**
* @Author: czn
* @Date 2020/11/18 22:24
*/
public class Client {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//设置目标类的字节码文件
enhancer.setSuperclass(Pursuit.class);
//设置回调函数
enhancer.setCallback(new cglibProxy(new Pursuit(new SchoolGirl("美美"))));
//生成代理对象
Pursuit pursuit = (Pursuit)enhancer.create();
//调用代理类的方法
pursuit.giveChoolate();
pursuit.giveFlowers();
pursuit.giveDolls();
}
}
3.3 结果
美美送你巧克力
美美送你鲜花
美美送你洋娃娃