zoukankan      html  css  js  c++  java
  • 动态代理Proxy和Cglib

     大概过程

     程序运行期间动态生成字节码文件,然后加载到内存里面,生成代理对象

     静态代理的时候,代理类和被代理类必须实现同一个接口,

     动态代理代码

    public class MyCalculator implements Calculator{
    
        @Override
        public int add(int i, int j){
            int result = i + j;
            return result;
        }
    
        @Override
        public int sub(int i, int j){
            int result = i - j;
            return result;
        }
    
        @Override
        public int mul(int i, int j){
            int result = i * j;
            return result;
        }
    
        @Override
        public int div(int i, int j){
            int result = i / j;
            return result;
        }
    }
    
    public class CalculatorProxy{
        public static Calculator getProxy(){
            // 获取类加载器
            ClassLoader classLoader = calculator.getClass().getClassLoader();
            // 获取要实现的接口
            Class<?> interfaces = calculator.getClass().getInterfaces();
            InvocationHandler h = new InvocationHandler(){
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
                    try{
                        Object result = method.invoke(calculator, args);
                        return result;
                    }catch(Exception e){
                        e.printStackTrace();
                    }                
                }
            }
            Proxy.newProxyInstance();
        }
    }
    
    public class Test{
        public static void main(String[] args){
            Calculator proxy = CalculatorProxy.getProxy(new MyCalculator());
            System.out.println(proxy.add(1,1));
            System.out.println(proxy.getClass());
        }
    }

     ASM是Java字节码操控框架,动态生成类或增强既有类的功能

     ASM可以直接产生二进制class文件,可以在类被加载前动态改变类的行为

     CGlib

    public class MyCalculator{
    
        public int add(int i, int j){
            int result = i + j;
            return result;
        }
        
        public int sub(int i, int j){
            int result = i - j;
            return result;
        }
    
        public int mul(int i, int j){
            int result = i * j;
            return result;
        }
    
        public int div(int i, int j){
            int result = i / j;
            return result;
        }
    }
    
    public class MyCglig implements MethodInterceptor{
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable{
            System.out.println("输出前");
            Object o = proxy.invokeSuper(obj, args);
            System.out.println("输出后");
            return o;
        }
    }
    
    public class Test{
        public static void main(String[] args){
            // 动态代理创建的class文件存储到本地
            System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "d:\code");
            // 创建cglib获取代理对象的操作对象
            Enhancer enhancer = new Enhancer();
            // 设置enhancer对象的父类
            enhancer.setSuperclass(MyCalculator.class);
            // 设置enhancer的回调对象
            enhancer.setCallback(new MyCglib());
            // 创建代理对象
            Object o = enchancer.create();
            MyCalculator MyCalculator = (MyCalculator)enhancer.create();
            MyCalculator.add(1, 1);
            System.out.println(MyCalculator.getClass());        
        }
    }
  • 相关阅读:
    常用模块汇总
    day 16 常用模块 time 和 datetime(1)
    二分法 函数式 模块
    day 15 模块 (3)
    vue require.context 检索文件夹内文件路径
    Node.js搭建本地服务,读取css/js/img/html等各种格式文件
    Nodejs搭建web服务器
    el-table横向滚动条固定在屏幕最下方显示
    IE浏览器 backspace键使浏览器回退
    vue ElementUI el-input 键盘enter事件 导致刷新表单问题
  • 原文地址:https://www.cnblogs.com/YC-L/p/14240478.html
Copyright © 2011-2022 走看看