java动态代理实现

来源:互联网 发布:9377皇图翅膀进阶数据 编辑:程序博客网 时间:2024/06/11 08:57

Spring AOP的源码中用到了两种动态代理来实现拦截切入功能:jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由内部java的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。


cglib做动态代理时不要求被代理类实现统一接口。


来看一个我自己编写的jdk和cglib例子:

加入

代理类:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import org.springframework.beans.factory.FactoryBean;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import dynamicProxy.service.IHandler;/** * Created by liukang Date: 2017/1/23 Time: 12:07 jdk 动态代理测试类T */public  class  MyInvocationHandlerTest <ProxyClass> implements FactoryBean<ProxyClass> {    private ProxyClass iHandler;    /**     * 代理类     */    private ProxyClass proxyIHandler;    private _ProxyTypeEnum proxyTypeEnum;    public MyInvocationHandlerTest(ProxyClass iHandler,_ProxyTypeEnum proxyTypeEnum){        this.iHandler = iHandler;        this.proxyTypeEnum = proxyTypeEnum;    }    public ProxyClass getObject() throws Exception {        if(this.proxyTypeEnum.equals(_ProxyTypeEnum.JDK)){            if (proxyIHandler == null) {                _InvocationHandler myInvocationHandler = new _InvocationHandler();                proxyIHandler = (ProxyClass) Proxy.newProxyInstance(this.iHandler.getClass().getClassLoader(),                        this.iHandler.getClass().getInterfaces(), myInvocationHandler);            }        }        if(this.proxyTypeEnum.equals(_ProxyTypeEnum.CGLIB)){            Enhancer e = new Enhancer();            e.setSuperclass(iHandler.getClass());            e.setCallback(new _CglibProxy());            proxyIHandler = (ProxyClass) e.create();        }        return proxyIHandler;    }    public Class<?> getObjectType() {        return IHandler.class;    }    public boolean isSingleton() {        return true;    }    public enum _ProxyTypeEnum{        JDK,CGLIB;    }    /**     * jdk代理类实现     */    public class _InvocationHandler implements InvocationHandler {        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            Object proxyObject = null;            if ("handle".equals(method.getName())) {                System.out.println("before handle!");                proxyObject = method.invoke(MyInvocationHandlerTest.this.iHandler, args);                System.out.println("end handle!");            } else {                proxyObject = method.invoke(MyInvocationHandlerTest.this.iHandler, args);            }            return proxyObject;        }    }    /**     * cglib代理类实现 cglib的好处是 代理的类不用都实现同一个接口     */    public class _CglibProxy implements MethodInterceptor{        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {            System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");            System.out.println(method.getName());            Object o1 = methodProxy.invokeSuper(o, objects);            System.out.println("++++++end " + methodProxy.getSuperName() + "++++++");            return o1;        }    }}

service层:

/** * Created by liukang * Date: 2017/1/23 * Time: 12:15 * 处理器接口 */public interface IHandler {    void handle(Object...objects);}
package dynamicProxy.service.impl;import dynamicProxy.model.UserEntity;import dynamicProxy.service.IHandler;/** * Created by liukang Date: 2017/1/23 Time: 12:28 姓名处理类 */public class NameHandler implements IHandler {    public void handle(Object... objects) {        System.out.println("nameHandler start!");        if (objects == null || objects.length < 1) {            System.out.println("nameHandler objects is null");            return;        }        UserEntity user = (UserEntity) objects[0];        user.setName(user.getName()+" Handle");        System.out.println("nameHandler done!");    }}
model层:

package dynamicProxy.model;/** * Created by liukang * Date: 2017/1/23 * Time: 12:48 */public class UserEntity {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public UserEntity(String name,int age){        this.name = name;        this.age = age;    }}

测试类:

import dynamicProxy.model.UserEntity;import dynamicProxy.service.IHandler;import dynamicProxy.service.impl.NameHandler;/** * Created by liukang * Date: 2017/1/23 * Time: 12:34 */public class TestProxy {    public static void main(String args[]){        //jdk        MyInvocationHandlerTest<IHandler> myInvocationHandlerTest = new MyInvocationHandlerTest(new NameHandler(),                MyInvocationHandlerTest._ProxyTypeEnum.JDK);        UserEntity user = new UserEntity("name",16);        try {            IHandler nameHandler = myInvocationHandlerTest.getObject();            nameHandler.handle(user);        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(user.getName());        //cglib        MyInvocationHandlerTest<IHandler> myInvocationHandlerTest2 = new MyInvocationHandlerTest(new NameHandler(),                MyInvocationHandlerTest._ProxyTypeEnum.CGLIB);        UserEntity user2 = new UserEntity("name2",18);        try {            IHandler nameHandler2 = myInvocationHandlerTest2.getObject();            nameHandler2.handle(user2);        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(user2.getName());    }}


0 0
原创粉丝点击