zoukankan      html  css  js  c++  java
  • 代理模式之动态代理

    动态代理:
      根据目标对象,在程序运行期自动装配目标对象的代理对象.
      优点:可以根据不同的对象,动态装配出对应的代理对象
      缺点:采用了反射,导致运行速度会有延迟,JDK的动态代理必须是实现了接口的类(如果不实现接口,可以使用CGLIB)

    接口类:UserManager.java

    package com.djpowernode.spring;
    
    public interface UserManager {
    
        public void addUser(String username, String password);
    }

    实现类:UserManagerImpl.java

    package com.djpowernode.spring;
    
    public class UserManagerImpl implements UserManager {
    
        @Override
        public void addUser(String username, String password) {
            System.out.println("--------UserManagerImpl.addUser()-----------------");
        }
    
    }

    动态代理类:UserManagerImplProxy.java

    package com.djpowernode.spring;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class UserManagerImplProxy implements InvocationHandler {
    
        private Object targetObject;
        
        public Object createObjectProxy(Object targetObject){
            this.targetObject = targetObject;
            //targetObject.getClass().getClassLoader()取得目标对象的类加载环境
            //targetObject.getClass().getInterfaces()取得目标对象的实现的所有接口
            //this,代理对象,就是该代理类本身,需要加入新的功能checkScurity()
            //Proxy.newProxyInstance()根据取得的信息,自动装配出代理对象并返回(在程序运行期自动装配)
            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                                          targetObject.getClass().getInterfaces(),
                                          this);
        }
        
        //重新InvocationHandler中的invoke()方法,会在生成代理对象的时候,自动执行该方法
        //根据调用的方法的不同,自动对该方法进行一次封装,执行对应的方法就是在执行invoke()方法
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object rect = null;
            //根据规则,只对add开始的方法代理,类型与Spring中代理实现(Pointcut,Advice)
            if(method.getName().startsWith("add123")){
                checkScurity();
                //method.invoke()取得对象执行的某个方法并执行该方法
                rect = method.invoke(targetObject, args);
                    }
            return rect;
        }
        
        //在代理类中根据需求需要添加的功能
        private void checkScurity(){
            System.out.println("-----------checkScurity()--------------");
        }
    
    }

    测试类:Client.java

    package com.djpowernode.spring;
    
    public class Client {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    //        UserManager userManager = new UserManagerImpl();
            UserManagerImplProxy proxy = new UserManagerImplProxy();
            UserManager userManager = (UserManager) proxy.createObjectProxy(new UserManagerImpl());
            userManager.addUser("张三", "123456");
        }
    
    }
  • 相关阅读:
    自动装配
    SpringMVC
    线程池的类型以及执行线程submit()和execute()的区别
    JDBC配置文件db.properties(Mysql) 及dbutils的编写
    tokuDB 安装与备份小记
    CentOS 7 安装 LEMP
    MySQL 闪回工具之 binlog2sql
    解决 MySQL 分页数据错乱重复
    ClickHouse 快速入门
    【理论篇】Percona XtraBackup 恢复单表
  • 原文地址:https://www.cnblogs.com/djoker/p/6242047.html
Copyright © 2011-2022 走看看