zoukankan      html  css  js  c++  java
  • Spring(七)动态代理

    在上一篇博客中简单写了一下静态代理,这里主要讲一下动态代理

    动态代理主要有两种

    JDK动态代理   CGLIB动态代理

    那这两种代理有什么区别呢?

    (根据自己的理解总结)

    1.JDK动态代理

    他的特点是:目标对象必须有接口

    他的实质是:创建了接口的一个实现类

    他运行的时机:程序运行时

    2.CGLIB动态代理

    他的特点是:在一个类型没有接口的情况下进行代理

    他的实质是:在内存中构建目标类型的子类

    他运行的时机是:编译时

    简单介绍完这两种代理后,就用个例子具体看怎么实现动态代理

    先做JDK动态代理

    准备一个接口ISomeService,接口中有一个方法doSome(),和一个这个接口的实现类SomeServiceImpl,并重写其中的方法,具体代码如下

    package demo15;
    
    /**
     * Created by mycom on 2018/3/8.
     */
    public interface ISomeService
    {
        public void doSome();
    }
    package demo15;
    
    /**
     * Created by mycom on 2018/3/8.
     */
    public class SomeServiceImpl implements ISomeService {
        public void doSome() {
            System.out.println("十点十分的复习");
        }
    }

    使用JDK动态代理不需要再配置文件中进行配置,所以现在直接进行测试,但是测试的时候不能使用单测,而是使用main方法进行测试

    package demo15;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * Created by mycom on 2018/3/8.
     */
    public class Test {
        public static void main(String[] args) {
            //首先创建一个接口的实现类
            final SomeServiceImpl service=new SomeServiceImpl();
            //在调用方法之前想使用动态代理记录一下日志,生成动态代理,返回的是接口
            ISomeService proxyInstance =(ISomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
                    service.getClass().getInterfaces(), new InvocationHandler() {
                        /**
                         *
                         * @param proxy  代理对象
                         * @param method  目标类型的方法
                         * @param args  方法的参数
                         * @return
                         * @throws Throwable
                         */
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            //在这里记录一下日志
                            System.out.println("before=====");
                            //调用method 的
                            method.invoke(service,args);//相当于执行目标类型的方法
                            System.out.println("after=======");
                            return null;
                        }
                    });
    
            //调用动态代理中的方法中的方法
            proxyInstance.doSome();
        }
    }

    运行的结果如下

    这说明运行时先执行了invoke方法,再执行接口中doSome的方法,实验成功!

    使用CGLIB动态代理实现上述中的运行结果,如何实现呢?

    这时就不用再创建接口了,(在这里我就使用上面的SomeServiceImpl这个类了,这个类中不用做改动),我直接进行测试了,测试还和上面一样,使用main方法测试,不用配置文件

    package demo09;
    
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * Created by mycom on 2018/3/8.
     */
    public class Test {
        public static void main(String[] args) {
            final SomeServiceImpl service=new SomeServiceImpl();
            Enhancer enhancer=new Enhancer();
            enhancer.setSuperclass(service.getClass());
            enhancer.setCallback(new MethodInterceptor() {
                /**
                 *
                 * @param o 代理对象
                 * @param method 目标类型的方法
                 * @param objects 目标方法的参数
                 * @param methodProxy 代理类的方法   是一个新的参数
                 * @return
                 * @throws Throwable
                 */
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("before=====");
                    methodProxy.invoke(service,objects);
                    System.out.println("after=====");
                    return null;
                }
            });
            SomeServiceImpl proxy =(SomeServiceImpl) enhancer.create();
            proxy.doSome();
        }
    }

    运行结果和上面的一样,这就是两种方法实现动态代理!

  • 相关阅读:
    hdu 5101 Select
    hdu 5100 Chessboard
    cf B. I.O.U.
    cf C. Inna and Dima
    cf B. Inna and Nine
    cf C. Counting Kangaroos is Fun
    Radar Installation 贪心
    spfa模板
    Sequence
    棋盘问题
  • 原文地址:https://www.cnblogs.com/my-123/p/8531479.html
Copyright © 2011-2022 走看看