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

静态代理与动态代理

作者: 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() )));
            
        }
    }
    
    

    相关文章

      网友评论

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

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