美文网首页
静态代理与动态代理

静态代理与动态代理

作者: atdoking | 来源:发表于2021-03-25 22:35 被阅读0次

说到静态代理与动态代理,这个可能是面试经常问到的,那么什么是代理呢?代理在正式的定义中是这样的:

Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问)

这句话说得简单明了,这也静态代理最直接的反应,那么静态代理的优点就呼之欲出了:扩展原功能,不侵入原代码;

当然这个缺点也是很明显的,如果有不同的类要代理,那么我们是要创建不同的代理类,或者代理类会随着业务方法的增加,我们的代理类也会跟随膨胀;

下面我们来说说代理类的具体实现吧:


image.png
package proxy;
import java.util.*;
 
public interface IGamePlayer {
 
    /**
     * @param String user 
     * @param Stirng paasword
     */
    public void login( String user,  String paasword);
 

    public  void killBoss();
 

    public  void upgrade();
 

    public  IGamePlayer getProxy();
 
}

代理类为:

package proxy;
import java.util.*;
 
public class GamePlayerProxy implements IGamePlayer {
    private IGamePlayer gamePlayer = null;
 
    /**
     * Default constructor
     */
    public GamePlayerProxy(IGamePlayer _gamePlayer) {
        this.gamePlayer = _gamePlayer;
    }
 
  
    /**
     * @param String user 
     * @param Stirng paasword
     */
    public void login( String user,  String paasword) {
        // TODO implement here
        this.gamePlayer.login(user, paasword);
    }
    public  void killBoss() {
        // TODO implement here
        this.gamePlayer.killBoss();
    }
 
    public  void upgrade() {
        // TODO implement here
        this.gamePlayer.upgrade();
    }
 
    public  IGamePlayer getProxy() {
        // TODO implement here
        return this;
    }
 
}

实际业务类:

package proxy;
import java.util.*;
 
/**
 * 
 */
public class GamePlayer implements IGamePlayer {
    private String name = "";
    private IGamePlayer proxy = null;
 
    /**
     * Default constructor
     */
    public GamePlayer(String _name) {
        this.name = _name;
    }
 
 
    /**
     * @param String user 
     * @param Stirng paasword
     */
    public void login( String user, String paasword) {
        // TODO implement here
        if(this.isProxy()){
            System.out.println("登录名为" + user + "的用户" + this.name + "登录成功!");
        }else{
            System.out.println("请使用指定的代理访问");
        }
    }
 
    /**
     * 
     */
    public  void killBoss() {
        // TODO implement here
        if(this.isProxy()){
            System.out.println(this.name + "在打怪!");
        }else{
            System.out.println("请使用指定的代理访问");
        }
    }
 
    /**
     * 
     */
    public  void upgrade() {
        // TODO implement here
        if(this.isProxy()){
            System.out.println(this.name + "又升了一级!");
        }else{
            System.out.println("请使用指定的代理访问");
        }
    }
 
    /**
     * 
     */
    public  IGamePlayer getProxy() {
        // TODO implement here
        this.proxy = new GamePlayerProxy(this);
        return this.proxy;
    }
    
    private boolean isProxy(){
        if(this.proxy == null){
            return false;
        }else{
            return true;
        }
    }
 
 
 
}

package proxy;
 
 
import java.text.SimpleDateFormat;
 
/**
 * 
 */
public class Client {
 
    /**
     * Default constructor
     */
    public static void main(String[] args) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        IGamePlayer player = new GamePlayer("张三");
        player.getProxy();
        System.out.println(String.format("开始时间是:%s",df.format( System.currentTimeMillis() )));
        player.login("wangfei", "123");
        player.killBoss();
        player.upgrade();
        System.out.println(String.format("结束时间是:%s",df.format( System.currentTimeMillis() )));
        
    }
 
 
}

image.png

那么什么又是动态代理呢,其实我们经常说的面向切面变成,这个AOP,其核心就是采用了动态代理机制。

使用动态代理的话就解决了静态代理的毛病,无论有多少业务类,我们都可以在运行的时候,生成一个持有业务类并实现代理接口的接口类proxy,同时注入我们相同的逻辑。无论是不同的对象,还是方法,都可以通过动态代理来扩展功能,不用重新来写一个代理类

主要也是使用InvocationHandler,这个是JDK提供的动态代理接口,对被代理的类方法进行代理。这样接口保持不变,实现类也不会变化


image.png

package proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class GamePlayIH implements InvocationHandler {
    Class cls = null;
    Object obj = null;
    
    public  GamePlayIH(Object _obj) {
        // TODO Auto-generated constructor stub
        this.obj = _obj;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        Object result = method.invoke(this.obj, args);
        return result;
    }
 
}

package proxy;
 
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;
 
public class Client1 {
 
    /**
     * Default constructor
     */
    public static void main(String[] args) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        IGamePlayer player = new GamePlayer("张三");
        InvocationHandler handler = new GamePlayIH(player);
        player.getProxy();
 
        System.out.println(String.format("开始时间是:%s",df.format( System.currentTimeMillis() )));
        
        ClassLoader c1 = player.getClass().getClassLoader();
        /*动态产生一个代理者*/
        IGamePlayer proxy = (IGamePlayer)Proxy.newProxyInstance(c1, new Class[]{IGamePlayer.class}, handler);
        proxy.login("wangfei", "123");
        proxy.killBoss();
        proxy.upgrade();
        System.out.println(String.format("结束时间是:%s",df.format( System.currentTimeMillis() )));
        
    }
}

相关文章

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • JAVA动态代理的实现方式

    1. 静态代理VS动态代理 代理类可以增强被代理对象的方法。可分为静态代理和动态代理。 1.1 静态代理 静态代理...

  • 带你初识Java的代理模式

    Spring AOP是基于动态代理设计模式实现的,相对的就有静态代理 动态代理和静态代理 静态代理 对于静态代理,...

  • Spring之代理模式

    九、代理模式 目录:静态代理、动态代理AOP的底层机制就是动态代理。代理模式分为静态代理和动态代理。接触aop之前...

  • Spring AOP中的动态代理

    Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理: (3)静态代理与动态代理区别...

  • 静态代理、动态代理

    代理分为静态代理和动态代理 按照代理创建的时期,可以分为静态代理和动态代理: (1) 静态代理:由程序员或者...

  • 动态代理

    目录: 1.动态代理与静态代理的使用区别2.动态代理实现原理3.动态代理的使用场景 1.静态代理 代理模式给某一个...

  • 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP

    文章目录 Java的静态代理 静态代理的优缺点 ABAP的静态代理 Spring AOP的动态代理 JDK动态代理...

  • SpringAOP-jdk动态代理

    静态代理与动态代理 静态代理(如SpringAOP-代理模式中所示)的缺点代理目标的方法越多,代理所委托的方法就越...

  • 静态代理

    静态代理, : //创建代理 总结静态代理: 解决: 可以使用动态代理。

网友评论

      本文标题:静态代理与动态代理

      本文链接:https://www.haomeiwen.com/subject/jdcdhltx.html