动态代理简介

来源:互联网 发布:ip攻击软件 编辑:程序博客网 时间:2024/04/29 01:03
1、什么是动态代理?
        说起动态,其实不如先说什么是静态。所谓静态代理,由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。总之,就是程序运行前就已经存在的编译好的代理类。

        相反,如果代理类程序运行前并不存在,在程序运行时,运用反射机制动态创建而成(无需手工编写代理类源码),那就是今天要说的动态代理了。

2、实现原理

        和动态代理有关的有两个类 

1)、interface InvocationHandler
Object invoke(Object proxy, Method method, Object[] args)
用来代理我们要做的N多事情。

2)、class Proxy
真正表示动态代理的类,提供两个静态方法:

Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface)
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,
用来冒充真实的对象。

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法

3)、代理图
       

3、代码展示

        1)、UserManager:

<span style="font-size:18px;">    public interface UserManager {        public void addUser(String userId,String userName);                public void delUser(String userId);                public void modifyUser(String userId,String userName);                public String QueryUser(String userId);    }</span>
2)、UserManagerImpl:
<span style="font-size:18px;">    public class UserManagerImpl implements UserManager {        @Override        public void addUser(String userId, String userName) {            System.out.println("UserManagerImpl.addUser()");        }        @Override        public void delUser(String userId) {            System.out.println("UserManagerImpl.delUser()");        }        @Override        public void modifyUser(String userId, String userName) {            System.out.println("UserManagerImpl.modifyUser()");        }        @Override        public String QueryUser(String userId) {            System.out.println("UserManagerImpl.QueryUser()");            return "zhangsan";        }    }</span>
3)、UserManagerImpl的动态代理:
<span style="font-size:18px;">    public class LogHandler implements InvocationHandler {        private Object targetObject;        public Object newProxyInstance(Object targetObject){            this.targetObject=targetObject;            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),                     targetObject.getClass().getInterfaces(), this);        }        @Override        public Object invoke(Object proxy, Method method, Object[] args)                throws Throwable {            System.out.println("start-->>"+ method.getName());            for (int i=0;i<args.length;i++){                System.out.println(args[i]);            }            Object ret=null;            try{                //调用目标方法                ret=method.invoke(targetObject, args);                System.out.println("success-->>"+ method.getName());            }catch(Exception e){                e.printStackTrace();                System.out.println("error-->>"+ method.getName());                throw e;            }            return ret;        }    }</span>
4)、客户端调用:
public static void main(String[] args) {        LogHandler logHandler=new LogHandler();        UserManager userManager=(UserManager)logHandler.newProxyInstance(new UserManagerImpl());        //userManager.addUser("1", "zhangsan");        String userName=userManager.QueryUser("1");        System.out.println("userName:"+userName);        }

1 0