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();
    
        }
    }
  • 相关阅读:
    使用Jenkins进行android项目的自动构建(3)
    使用Jenkins进行android项目的自动构建(2)
    使用Jenkins进行android项目的自动构建(1)
    testlink 从1.8.5 升级到 1.9.8
    779. 第K个语法符号(Leetcode)
    687. 最长同值路径(Leetcode)(递归+树)
    116. 飞行员兄弟(Acwing)(递归+位运算)
    95. 费解的开关(Acwing)(分析+递推)
    Java遇到输入速度瓶颈时的解决办法
    92. 递归实现指数型枚举(Acwing)(递归)
  • 原文地址:https://www.cnblogs.com/java-263/p/10006809.html
Copyright © 2011-2022 走看看