0
点赞
收藏
分享

微信扫一扫

【代理模式】静态代理,动态代理


前言:学习自https://www.bilibili.com/video/BV1WE411d7Dv?p=19

文章目录

  • ​​代理模式​​
  • ​​静态代理模式​​
  • ​​1、介绍​​
  • ​​2、例子:婚介公司​​
  • ​​3、优点​​
  • ​​动态代理模式​​
  • ​​1、介绍​​
  • ​​2、例子:租房中介公司​​
  • ​​3、优点​​

代理模式

静态代理模式

1、介绍

1、真实角色和代理角色要实现同一个接口
2、代理角色要代理真实角色
3、给代理角色添加set方法(属性为接口,从而解耦合),将某个真实角色注入到代理角色的属性中,以便调用

2、例子:婚介公司

public class StaticProxyTest {
public static void main(String[] args) {
You you = new You();
WeddingCompany weddingCompany = new WeddingCompany();
weddingCompany.setMarry(you);
/*
这也是多线程Thread的原理
new Thread(一个实现Runnable接口的类).start(),而且Thread本身也实现了Runnable接口
*/

weddingCompany.HappyMarry();
}
}

interface Marry {
void HappyMarry();
}

//真实角色,你去结婚
class You implements Marry {
@Override
public void HappyMarry() {
System.out.println("Marry~");
}
}

//代理角色,帮你结婚
class WeddingCompany implements Marry {

private Marry target;

public void setMarry(Marry target) {
//传入真实角色
this.target = target;
}

@Override
public void HappyMarry() {
before();
this.target.HappyMarry(); //真实角色
after();
}

private void before() {
System.out.println("before--arrangement~");
}

private void after() {
System.out.println("after--clear~");
}
}

【代理模式】静态代理,动态代理_设计模式

3、优点

代理角色可以做真实角色分外的事,从而真实角色专注做自己分内的事

动态代理模式

1、介绍

  • 动态代理的角色和静态代理的一样
  • 动态代理的代理类是动态生成的,静态代理的代理类是我们提前写好的
  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
    (1)基于接口的动态代理----JDK动态代理
    (2)基于类的动态代理----cglib
    (3)现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist

JDK的动态代理需要了解两个类:

  • InvocationHandler
  • 【代理模式】静态代理,动态代理_代理类_02

  • Proxy
  • 【代理模式】静态代理,动态代理_proxy_03

2、例子:租房中介公司

public class DynamicProxyTest {
public static void main(String[] args) {
//真实角色
Host host = new Host();

//代理实例的调用处理程序
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); //将真实角色放置进去!
Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
proxy.rent();
}
}

//接口
interface Rent {
public void rent();
}

//真实角色: 房东,房东要出租房子
class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
}

//代理角色:中介
class ProxyInvocationHandler implements InvocationHandler {

private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}

//生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
// proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//核心:本质利用反射实现!
Object result = method.invoke(rent, args);
fare();
return result;
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}

【代理模式】静态代理,动态代理_设计模式_04


更有普适性的例子(优化了 ProxyInvocationHandler 类):

public class DynamicProxyTest {
public static void main(String[] args) {
//真实角色
Host host = new Host();

//代理角色
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(host); //将真实角色放置进去!
Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
proxy.rent();
}
}

//接口
interface Rent {
public void rent();
}

//真实角色: 房东,房东要出租房子
class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
}

//代理角色:中介
class ProxyInvocationHandler implements InvocationHandler {

private Object target;

public void setTarget(Object target) {
this.target = target;
}
//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
// proxy : 代理类
// method : 代理类的调用处理程序的方法对象.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String methodName){
System.out.println("执行了"+methodName+"方法");
}
}

【代理模式】静态代理,动态代理_设计模式_05

3、优点

(包含了静态代理的优点)

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情
  • 公共的业务由代理来完成 . 实现了业务的分工
  • 公共业务发生扩展时变得更加集中和方便
  • 一个动态代理 , 一般代理某一类业务
  • 一个动态代理可以代理多个类,代理的是接口


举报

相关推荐

0 条评论