java代理模式

1、静态代理

1、角色分析:

  • 抽象角色:共同完成的一件事情,一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作。
  • 客户:访问代理对象的人!

2、代码步骤:

//结婚
interface Marry{
void HappyMarry();
}


2. ```java
// 你去结婚
class You implements Marry{

    @Override
    public void HappyMarry() {
        System.out.println("我要结婚了");
    }
}

// 代理对象,帮助你结婚
class WeddingCompany implements Marry{
private Marry target;

   public WeddingCompany(Marry target) {
       this.target = target;
   }

   @Override
   public void HappyMarry() {
       before(); // 帮你布置现场
       this.target.HappyMarry(); // 你去结婚
       after(); // 收尾款 
   }
   private void before() {
       System.out.println("布置现场");
   }

   private void after() {
       System.out.println("收尾款");
   }

}


4. ```java
public class StaticProxy {
    public static void main(String[] args) {
        // 代理对象帮你布置现场  收尾款
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.HappyMarry();// 你只需要自己结婚即可
    }
}

3、静态代理的好处:

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

4、缺点:

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

2、动态代理

1、JDK 动态代理

1、使用 JDK 动态代理,使用 Proxy类里面的方法创建代理对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMuZaHNI-1607480522120)(img/image-20200922200209368.png)]

Proxy 提供用于创建动态代理类和实例的静态方法

调用 newProxyInstance 方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ao7agMRD-1607480522123)(img/image-20200922200457006.png)]

方法中有三个参数:

  • 第一个参数:类加载器

  • 第二个参数:增强方法所在的类,这个类实现的接口,支持多个接口

  • 第三个参数:实现这个接口 InvocationHandler,创建代理对象,写增强的方法

2、步骤

1、创建接口,定义方法

public interface UserDao {
    int add(int a,int b);
    String update(String id);
}

2、创建接口实现类,实现方法

public class UserDaoImpl implements UserDao {
    @Override
    public int add(int a, int b) {
        System.out.println("add方法执行了。。。。");
        return a+b;
    }

    @Override
    public String update(String id) {
        System.out.println("update方法执行了。。。。");
        return id;
    }
}

3、使用 Proxy 类创建接口代理对象

package com.yb.spring5;

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

public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfaces = {UserDao.class};

/*        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
            @Override //匿名内部类,或者创建一个类,然后这里写上类对象
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return null;
            }
        });*/

        UserDaoImpl userDao = new UserDaoImpl();
        //获取代理对象
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        //调用对应的方法
        int res = dao.add(1, 2);
        System.out.println("结果:"+res);
    }
}

//创建代理对象代码
class UserDaoProxy implements InvocationHandler{

    //1、创建的是谁的代理对象,把谁传递过来
    private Object obj;
    //有参数构造传递
    public UserDaoProxy(Object obj){
        this.obj = obj;
    }

    //增强的逻辑
    //参数 proxy:代理对象
    //参数 method:当前的方法
    //参数 args:参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行..."+method.getName()+"方法:传递的参数"+ Arrays.toString(args));
        //被增强的方法执行
        Object res = method.invoke(obj, args);
        //方法之后
        System.out.println("方法之后执行..."+obj);

        return res;
    }
}
//结果
方法之前执行...add方法:传递的参数[1, 2]
add方法执行了。。。。
方法之后执行...com.yb.spring5.UserDaoImpl@355da254
结果:3

动态代理的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共也就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
    方法:传递的参数[1, 2]
    add方法执行了。。。。
    方法之后执行…com.yb.spring5.UserDaoImpl@355da254
    结果:3



动态代理的好处:

* 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
* 公共也就交给代理角色!实现了业务的分工!
* 公共业务发生扩展的时候,方便集中管理!
* 一个动态代理类代理的是一个接口,一般就是对应的一类业务
* 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java代理模式是一种结构型设计模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。代理对象可以在客户端和目标对象之间充当中介,以便于客户端访问目标对象时,可以在不改变目标对象的情况下添加一些额外的功能,比如安全性、远程访问、缓存等。 在Java中,代理模式可以通过两种方式实现:静态代理和动态代理。静态代理需要手动编写代理类,而动态代理可以在运行时通过反射机制动态生成代理类,更加灵活。 举个例子,假设我们有一个接口`Subject`,其中定义了一些方法。我们希望在调用这些方法时,增加一些额外的日志记录功能。我们可以编写一个代理类`SubjectProxy`,在代理类中实现接口方法并调用目标对象的方法,同时在方法前后添加日志记录的代码。客户端则通过代理类访问目标对象。 静态代理示例代码如下: ```java public interface Subject { void doSomething(); } public class RealSubject implements Subject { @Override public void doSomething() { System.out.println("RealSubject do something."); } } public class SubjectProxy implements Subject { private Subject realSubject; public SubjectProxy(Subject realSubject) { this.realSubject = realSubject; } @Override public void doSomething() { System.out.println("Before do something."); realSubject.doSomething(); System.out.println("After do something."); } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); Subject subjectProxy = new SubjectProxy(realSubject); subjectProxy.doSomething(); } } ``` 动态代理示例代码如下: ```java public class SubjectHandler implements InvocationHandler { private Object target; public SubjectHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before " + method.getName()); Object result = method.invoke(target, args); System.out.println("After " + method.getName()); return result; } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); InvocationHandler handler = new SubjectHandler(realSubject); Subject subjectProxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); subjectProxy.doSomething(); } } ``` 无论是静态代理还是动态代理,代理模式都可以在不改变目标对象的情况下,为其添加额外的功能,提高代码的可复用性和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值