zoukankan      html  css  js  c++  java
  • Spring 静态代理+JDK动态代理和CGLIB动态代理

    代理分为两种:静态代理  动态代理

    静态代理:本质上会在硬盘上创建一个真正的物理类

    动态代理:本质上是在内存中构建出一个类。

    如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间。而动态代理则是在内存中创建,不会对磁盘进行影响。

    静态代理和JDK动态代理需要有接口。  CGLIB动态代理无需有接口的情况下进行代理。实质:内存中构建出了目标类型的子类。

    JDK动态代理是JDK提供的,CGLIB动态代理是Spring提供的。

    代理模式的三个组件:抽象主题  真实主题  代理主题

    静态代理:

       接口(抽象主题)的代码:

    //抽象主题
    public interface Subject {
        public void request();
    }

      目标对象(真实主题)的代码:

    //真实主题
    public class RealSubject implements Subject{
        @Override
        public void request() {
            System.out.println("Subject     RealSubject");
        }
    }

      代理对象(代理主题)的代码:

    package cn.Spring.Day09Staticporxy;
    //代理主题
    public class ProxySubject implements Subject {
        //把真实主题当成代理主题的成员变量
        private RealSubject rs=new RealSubject();
        @Override
        public void request() {
            System.out.println("proxy");//在调用真实主题要增强的方法前进行增强
            rs.request();
            System.out.println("ProxySubject");//在调用真实主题要增强的方法后进行增强
        }
    }

    JDK动态代理:

      接口:

    package cn.Spring.Day14JDKproxy;
    
    public interface ISomeService {
        public void request();
    }

      目标对象:

    package cn.Spring.Day14JDKproxy;
    
    public class SomeService implements ISomeService {
        @Override
        public void request() {
            System.out.println("977+7777");
        }
    }

      代理对象:

    package cn.Spring.Day14JDKproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkProxy {
        public static void main(String[] args) {
            /*
            * 1.使用Proxy点出newProxyInstance方法     方法有三个参数
            *                                 ClassLoader loader,    类加载器类型的一个对象
            *                                 Class<?>[] interfaces,接口数组对象
            *                                 InvocationHandler h    InvocationHandler 对象
            * 2.实例化目标对象 目标对象去传入参数。
            * 3.invoke方法中使用method.invoke传入目标对象,和参数数组。
            * 
            * 
            * */
            final SomeService ss=new SomeService();
            ISomeService proxy = (ISomeService)Proxy.newProxyInstance(ss.getClass().getClassLoader(), ss.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("我是增强666666");
                    method.invoke(ss,args);
                    return null;
                }
            });
            proxy.request();
        }
    }
    newProxyInstance要传的参数

    invoke要传的参数

     

    CGLIB动态代理:

    目标对象:

    package cn.Spring.Day10cglibProxy;
    
    public class Service {
        public void doSome(){
            System.out.println("SSSSSService");
        }
    }

    代理对象:

    package cn.Spring.Day10cglibProxy;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class ServiceTest {
        public static void main(final String[] args) {
            final Service service=new Service();
            Enhancer enhancer=new Enhancer();
            enhancer.setSuperclass(Service.class);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("写入日志");
                    Object invoke = methodProxy.invoke(service, args);
                    return invoke;
                }
            });
            Service o = (Service)enhancer.create();
            o.doSome();
    
        }
    }
  • 相关阅读:
    Emacs和ESS的使用技巧。
    响应式
    Day learn,day up
    Docker快速安装kafka | 沈健的技术博客
    闭包函数如何使用循环变量
    leetcode笔记——35.搜索插入位置
    CSS 之动态变换背景颜色
    吴裕雄 PYTHON 神经网络——TENSORFLOW 双隐藏层自编码器设计处理MNIST手写数字数据集并使用TENSORBORD描绘神经网络数据2
    吴裕雄 PYTHON 神经网络——TENSORFLOW 双隐藏层自编码器设计处理MNIST手写数字数据集并使用TENSORBORD描绘神经网络数据
    吴裕雄 PYTHON 神经网络——TENSORFLOW 单隐藏层自编码器设计处理MNIST手写数字数据集并使用TensorBord描绘神经网络数据
  • 原文地址:https://www.cnblogs.com/java-263/p/10006809.html
Copyright © 2011-2022 走看看