代理模式中的静态代理和动态代理

代理模式

1、为什么要学代理模式:

代理模式是spring AOP的底层【springAOP和springMVC】

2、代理模式分类:

Ⅰ、静态代理

  • 角色分析:
  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真是角色:被代理的角色
  • 代理角色:代理真实角色,代理后我们一般会做一些附属操作
  • 客户:访问代理对象的人

代码步骤:

1、接口

public interface Rent {
    public void rent();
}

2、真实角色

public class Host implements Rent{

    public void rent() {
        System.out.println("我是房东,我要出租房子");
    }
}

3、代理角色

public class Proxy implements Rent{
    private Host host;

    public Proxy(Host host) {
        this.host = host;
    }
    public Proxy() {
    }
    public void rent() {
        host.rent();
    }
}

4、客户端访问代理角色

public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        Proxy p=new Proxy(host);
        //直接找中介
        p.rent();
    }
}

代理模式的好处:

  • 可以使得真实角色业务更加纯粹,不用去关注一些工共的事务
  • 工共的业务交给代理角色,实现了业务的分工
  • 工共业务发生扩展的时候,方便集中管理

代理模式缺点:

  • 一个真实角色就会产生一个代理角色:代码量会翻倍,开发效率会变低

Ⅱ、动态代理

  • 动态代理和静态代理是一样的
  • 动态代理的代理类是动态生成的,不是我们直接写
  • 动态代理分两大类,基于接口的动态代理,基于类的动态代理类
    1. 基于接口:JDK动态代理
    2. 基于类:cglib
    3. Java字节码实现:Javassist

需要了解的两个类:

proxy:代理

提供了动态代理类和实例的静态方法,它是由这些方法创建的所有动态代理类的超类

提供四个方法:getInvoationHandler(object proxy),newproxyInstance(Classloader loader)

InvocationHandler:调用 处理程序

是反射包下的:java.lang.reflect reflect(反射)

只有一个方法:invoke{object proxy,方法,method,Object[] args}

【注意】

InvocationHandler是接口,用来实现,Proxy是用来生成代理对象

–proxy 该方法的代理实例

–method调用这个类上的方法,也可以是一个接口

–args:固定的方法里面传递什么参数

动态代理的好处:

  • 可以使真是角色操作更加纯粹,不用去处理一些公共的事务
  • 公共事务也就交给代理角色,实现了业务的分工
  • 公共业务发生扩展时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般对应一类业务
  • 一个动态代理类可以代理多个类,只要实现多个接口即可!

程序流程

接口Rent

public interface Rent {
    public void rent();
}

真实角色

public class Host implements Rent{
    public void rent(){
        System.out.println("我是房东,我要出租房子");
    }
}

ProxyInvocationHandler

//我们会用这个类实现自动生成代理类
public 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);
    }

//处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //动态代理的本质就是使用反射实现的
        Object result=method.invoke(rent,args);
        return result;
    }
}

当然上面ProxyInvocationHandler也可以 写成一个工具类,用Object实现,就可以任意调用了

package com.asiainfo.demo4;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public 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);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       Object result=method.invoke(target,args);
        return result;
    }
}

Client(客户端)

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

        //代理角色,我们暂时没有
        ProxyInvocationHandler pih=new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象
        pih.setRent(host);
        //下面的proxy是动态生成的我们并没有去写。
        Rent proxy=(Rent) pih.getProxy();
        proxy.rent();
    }
}

总结

1、创建接口

2、创建真实对象

3、代理接口实现InvocationHandler,然后在实现InvacationHandler的类下面,用Proxy获取代理对象。

4、客户端调用,真实角色,代理角色,但是没有代理角色,所以通过InvacationHandler接口的实现类下面的getProxy()方法获取代理对像proxy,利用set注入真实对象,然后动态生成代理对象,如:Rent proxy=(Rent) pih.getProxy();之后直接点就出来了如,proxy.rent();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值