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();
    
        }
    }
  • 相关阅读:
    hive报错 java.sql.SQLException: No suitable driver found for jdbc:hive://localhost:10000/default
    使用Beeline连接Hive
    hive报错 root is not allowed to impersonate root (state=08S01,code=0)
    hive报错 Could not open client transport with JDBC Uri: jdbc:hive2://node01:10000/default:java.net.ConnectException refused
    excel快速删除空值单元格,数据上移
    FineBI 图表选择
    数据库连接池大小设置?
    工作中有待留❤️积累的一些经验
    内存包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE)。RAM最重要
    我自己ood的复习思路:抄
  • 原文地址:https://www.cnblogs.com/java-263/p/10006809.html
Copyright © 2011-2022 走看看