代理模式

代理模式

1.静态代理

静态代理角色:
1.抽象角色:一般以接口或者抽象类实现

2.真实角色:继承抽象类或者实现接口中的方法,被代理的角色

3.代理角色:代理真实角色,一般会在真是角色的基础上附加一些操作

4.客户端:使用代理角色进行操作

抽象角色:

实现基本的crud

public interface Book {
    public void add();
    public void delete();
    public void update();
    public void select();
}
真实角色:
public class BookImpl implements Book{
    public void add() {
        System.out.println("增加一本书");
    }
    public void delete() {
        System.out.println("删除一本书");
    }
    public void update() {
        System.out.println("修改一本书");
    }
    public void select() {
        System.out.println("查询一本书");
    }
}
代理角色:
public class Proxy implements Book{

    private BookImpl book;

    public void setBook(BookImpl book) {
        this.book = book;
    }
    public void logsBefore(){
        System.out.println("操作执行前");
    }
    public void logsAfter(){
        System.out.println("操作执行后");
    }
    public void add() {
        logsBefore();
        book.add();
        logsAfter();
    }
    public void delete() {
        logsBefore();
        book.delete();
        logsAfter();
    }
    public void update() {
        logsBefore();
        book.update();
        logsAfter();
    }
    public void select() {
        logsBefore();
        book.select();
        logsAfter();
    }
}

客户端(测试类):
    @Test
    public void test(){
        //真实业务
        BookImpl book=new BookImpl();
        //代理类
        Proxy proxy=new Proxy();
        //传入真实角色,使用代理类
        proxy.setBook(book);
        proxy.add();
        System.out.println("==========");
        proxy.delete();
        System.out.println("==========");
        proxy.update();
        System.out.println("==========");
        proxy.select();
        System.out.println("==========");

    }
}

静态代理可以实现基本的在不改变源代码的基础上,对原来的代码增加一些新的功能,实现对原有功能的增强,这也是Spring AOP中最核心的思想

2.动态代理

1.角色分布和静态代理的一样

2.代理类是动态生成的,而静态代理是手动写好的

方法:

​ 1.基于接口的动态代理----JDK动态代理

​ 2.基于类的动态代理–cglib

本次利用JDK实现动态代理:

核心: InvocationHandler 接口和 Proxy类

InvocationHandler 接口:

InvocationHandler是由代理实例的调用处理程序实现的接口,每个代理实例都有一个关联的调用处理程序,当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法

Object invoke(Object proxy, 方法 method, Object[] args)//proxy - 调用该方法的代理实例 
//method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。 
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。 
Proxy类:

本类提供了创建动态代理类和实例的静态方法,他也是有这些方法创建的所有动态代理类的父类

生成代理类的方法:
//生成代理类
public Object getProxy(){
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                                  rent.getClass().getInterfaces(),this);
}
抽象角色:
public interface Service {
    public void add();
    public void delete();
    public void update();
    public void query();
}
真实角色:
public class ServiceImpl implements Service {
    public void add() {
        System.out.println("增加一个用户");
    }
    public void delete() {
        System.out.println("删除一个用户");
    }
    public void update() {
        System.out.println("更改一个用户");
    }
    public void query() {
        System.out.println("查询一个用户");
    }
}

代理角色:
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Service service;

    public void setService(Service service) {
        this.service = service;
    }
    //生成并返回一个代理类
    public Object getproxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                service.getClass().getInterfaces(),this);
    }
    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());//利用反射获取方法名
        Object method1=method.invoke(service,args);
        return method1;
    }
    public void log(String xxx){
        System.out.println("执行了一个"+xxx+"方法");
    }
}
客户端(测试类):
public class Client {
    public static void main(String[] args) {
        //真实角色
        ServiceImpl service=new ServiceImpl();
        //代理角色,现在没有生成
        ProxyInvocationHandler proxyInvocationHandler=new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象
        proxyInvocationHandler.setService(service);
        Service service1= (Service) proxyInvocationHandler.getproxy();//这里动态生成了代理类
        service1.delete();
        service1.add();
        service1.update();
        service1.query();

    }
}

我们也可以编写一个通用的动态代理实现的类!所有的代理对象设置为Object即可!

动态代理的好处:

1.静态代理有的它都有,静态代理没有的,它也有!

2.可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .

3.公共的业务由代理来完成 . 实现了业务的分工 ,

4.公共业务发生扩展时变得更加集中和方便 .

5.一个动态代理 , 一般代理某一类业务

6.一个动态代理可以代理多个类,代理的是接口!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值