• Jdk动态代理与Cglib动态代理


      本文介绍动态代理的两种方式,作为Spring AOP的引入。

    一、JDK动态代理实现

    package dynamicProxyTest;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    interface Print{
        void print();
    }
    /**
     * 目标方法
     */
    class JdkTarget implements Print{//目标类需要保证有接口定义
        public void print(){
            System.out.println("hello jdkProxy");
        }
    }
    /**
     * 需要自定义一个处理器,实现InvocationHandler的invoke方法
     */
    class MyInvocationHandler implements InvocationHandler{
        Object target ;
        public MyInvocationHandler(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object obj = null ;
            //jdk动态代理中没有提供类似cglib中的过滤器,所以只能采取这种方式过滤掉对于"toString()"的增强
            if(method.getName().startsWith("print")) {
                System.out.println("before");
                obj = method.invoke(target, args);
                System.out.println("after");
            }else {
                obj = method.invoke(target, args);
            }
            return obj;
        }
        
    }
    /**
     * 测试类 
     */
    public class JdkProxy {
        public static void main(String[] args) {
            MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new JdkTarget());
            Print p = (Print) Proxy.newProxyInstance(JdkTarget.class.getClassLoader(), JdkTarget.class.getInterfaces(), myInvocationHandler);
            p.print();
            System.out.println(p.toString());
        }
    }
    before
    hello jdkProxy
    after
    dynamicProxyTest.JdkTarget@6bc7c054

    二、Cglib动态代理实现

    package dynamicProxyTest;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Callback;
    import net.sf.cglib.proxy.CallbackFilter;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    import net.sf.cglib.proxy.NoOp;
    /**
     * 目标类
     */
    class CglibTarget{//目标类不需要有实现接口
        void print(){
            System.out.println("hello cglibProxy");
        }
    }
    /**
     * 拦截器,实现MethodInterceptor的iintercept()方法
     */
    class MyMethodInterceptor implements MethodInterceptor{
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("BeforeInterceptor");
            Object returnValue = methodProxy.invokeSuper(obj, args);
            System.out.println("AfterInterceptor");
            return returnValue;
        }
        
    }
    /**
     * 过滤器
     */
    class MyMethodFilter implements CallbackFilter{
    
        @Override
        public int accept(Method method) {
            if(method.getName().startsWith("print")) {
                return 0;//使用自定义拦截器MyMethodInterceptor
            }else {
                return 1;//使用空拦截器NoOp.INSTANCE,即什么也进行增强处理
            }
        }
    }
    
    /**
     * 测试类
     */
    public class CglibProxy {
    
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(CglibTarget.class);
            enhancer.setCallbacks(new Callback[] {new MyMethodInterceptor(),NoOp.INSTANCE});
            enhancer.setCallbackFilter(new MyMethodFilter());
            CglibTarget target = (CglibTarget) enhancer.create() ;
            target.print();
            System.out.println(target.toString());
        }
    
    }
    BeforeInterceptor
    hello cglibProxy
    AfterInterceptor
    dynamicProxyTest.CglibTarget$$EnhancerByCGLIB$$4318edbe@1b4fb997
    "我们所要追求的,永远不是绝对的正确,而是比过去的自己更好"
  • 相关阅读:
    Thread类常用方法
    sql 语句NVL()用法
    SQL极限函数limit()详解<分页必备>
    查询用户上次登录时间问题
    ROWNUM-Oracle中的分页代码
    分组统计查询
    Oracle中的多表查询
    Oracle中的单行函数
    JDBC中的事务-Transaction
    MySql中增加一列
  • 原文地址:https://www.cnblogs.com/zomicc/p/12255510.html
Copyright © 2020-2023  润新知