美文网首页
java动态代理

java动态代理

作者: 冷枫abc | 来源:发表于2018-12-29 11:15 被阅读0次

    什么是动态代理?

    假如我有一个user对象,该对象里面有4个方法,增、删、改、查,外界能直接调用这4个方法吗?拿百度来说,你能随便对百度上的内容进行增、删、改、查操作吗?你最多能执行查的操作,增、删、改的操作是不能执行的,你必须要加一个权限操作,应该看看你是否有权限执行这个操作。同理,谁操作了这个东西,你需要给我留下记录,免得我不知道是谁做的。所以,我应该在每一个方法的前面加权限校验,在每一个方法的后面加日志记录。

    该怎么做呢?

    有人说,很简单,直接在user对象的实现类里面去改,在增、删、改查前面加上权限校验,在后面加上日志记录。你能随便改别人的代码吗?你一改,所以用过user对象的地方都要改,这不乱套了吗?

    有人说,可以再重新创建一个user对象,在新对象中加上权限校验和日志记录。确实是这样。但是如果我还有一个学生类,还有一个老师类...等等,你每一个都新创建一个对象的话,太麻烦了,而且没有必要,因为对我来说,我只关心对象的增、删、改、查操作,对于权限校验和日志记录我并不关心,这个时候,我们可以找中介来做权限校验和日志记录的事情,这个中介就是动态代理对象!

    动态代理

    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。

    举例:春季回家买票让人代买

    动态代理:在程序运行过程中产生的这个对象

    而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

    在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib

    Proxy类中的方法创建动态代理类对象

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

    最终会调用InvocationHandler的方法

    InvocationHandler

    Object invoke(Object proxy,Method method,Object[] args)

    jdk动态代理

    首先定义接口

    /**

    * 接口

    */

    interface IHello {

        void sayHello();

    }

    定义类实现接口和方法

    /**

    * IHello接口实现类

    */

    class Helloimplements IHello {

        public void sayHello() {

            System.out.println("Hello world!!");

        }

    }

    编写代理类

    class JdkProxyTestimplements InvocationHandler {

            private Objecttarget;

            public JdkProxyTest(Object target){

                this.target = target;

            }

        @Override

        public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {

                System.out.println("我是代理之前所做的操作");

                Object invoke = method.invoke(target, args);

                System.out.println("我是代理之后所做的操作");

                return invoke;

        }

    }

    书写主函数调用

    public class JdkProxy {

        public static void main(String[] args) {

                IHello iHello =new Hello();//接口新建所想要代理的类

                JdkProxyTest jdkProxyTest =new JdkProxyTest(iHello);

                IHello o = (IHello)Proxy.newProxyInstance(iHello.getClass().getClassLoader(), iHello.getClass().getInterfaces(), jdkProxyTest);

                o.sayHello();

        }

    }

    CGLIB代理

    cglib动态代理需要引入cglib的相关jar包

    compilegroup:'cglib',name:'cglib',version:'3.2.10'

    /**

    * 目标对象,没有实现任何接口

    */

    class Singer{

    public void sing() {

        System.out.println("唱一首歌");

    }

    }

    /**

    * 代理类

    */

    class ProxyFactoryimplements MethodInterceptor {

            private Objecttarget;

            public Object getInvoke(){

            Enhancer enhancer =new Enhancer();

            enhancer.setSuperclass(Singer.class);

            enhancer.setCallback(this);

            return enhancer.create();

    }

    @Override

        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)throws Throwable {

                System.out.println("执行代理前");

                Object invokeSuper = proxy.invokeSuper(obj, args);

                System.out.println("执行代理后");

                return invokeSuper;

    }

    }

    public class CglibProxy {

                public static void main(String[] args) {

                ProxyFactory pf =new ProxyFactory();

                Singer s = (Singer)pf.getInvoke();

                s.sing();

    }

    }

    相关文章

      网友评论

          本文标题:java动态代理

          本文链接:https://www.haomeiwen.com/subject/eqyelqtx.html