zoukankan      html  css  js  c++  java
  • 动态代理,AOP和Spring

    笔记

    1. 什么是AOP?

    Aspect-Oriented Programming 面向切面编程,关注一个统一的切面,相对于OOP(面向对象编程)。

    适合的场景

    • 日志
    • 缓存
    • 鉴权

    如果用OOP来做怎么办?

    • 装饰器模式

    2. 装饰器模式 (OOP, 静态代理)

    Decorator pattern:
    动态地为一个对象增加功能,但是不改其结构。

    public interface DataService {
        String a(int i);
    
        String b(int i);
    }
    
    public class DataServiceImpl implements DataService {
        @Override
        public String a(int i) {
            return UUID.randomUUID().toString();
        }
    
        @Override
        public String b(int i) {
            return UUID.randomUUID().toString();
        }
    }
    
        public class Main {
        static DataService service = new CacheDecorator(new LogDecorator(new DataServiceImpl()));
    
        public static void main(String[] args) {
            System.out.println(service.a(1));
            System.out.println(service.b(1));
        }
    }
    
    

    假如是class,就会有浪费。

    3. AOP动态代理

    public class LogProxy implements InvocationHandler {
        private DataService delegate;
    
        public LogProxy(DataService delegate) {
            this.delegate = delegate;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(method.getName() + " is invoker " + Arrays.toString(args));
            Object result = method.invoke(delegate, args);
            System.out.println(method.getName() + " is finished: " + result);
            return result;
        }
    }
    
    public class Main {
        static DataService service = new DataServiceImpl();
    
        public static void main(String[] args) {
            DataService dataService = (DataService) Proxy.newProxyInstance(
                    service.getClass().getClassLoader(),
                    new Class[]{DataService.class},
                    new LogProxy(service));
            dataService.a(1);
            dataService.b(3);
        }
    }
    

    优点:方便,不需要依赖任何第三方库
    缺点:功能受限,只能用于接口 (源代码中接收参数为interface,如果是class会报异常)

    4. 如果是class怎么办?

    CGLIB/ByteBuddy字节码生成

    public class Main {
        static DataServiceImpl service = new DataServiceImpl();
    
        public static class LogInterceptor implements MethodInterceptor {
            private DataServiceImpl delegate;
    
            public LogInterceptor(DataServiceImpl delegate) {
                this.delegate = delegate;
            }
    
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println(method.getName() + " is invoker " + Arrays.toString(objects));
                Object result = method.invoke(delegate, objects);
                System.out.println(method.getName() + " is finished: " + result);
                return result;
            }
        }
    
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(DataServiceImpl.class);
            enhancer.setCallback(new LogInterceptor(service));
            DataServiceImpl enhancedService = (DataServiceImpl) enhancer.create();
            enhancedService.a(1);
            enhancedService.b(2);
    }
    
    // 这里会动态生成一个叫做DataServiceImpl$$EnhancerByCGLIB$$9bce1175@651的类,它是动态生成出来,并且是继承我们的DataServiceImpl的。
    

    优点:强大,不受接口的限制
    缺点:需要额外引用第三方库,不能增强final类/final/private方法(因为原理是继承)。

  • 相关阅读:
    STL 清除模板容器 clear.h
    建立ORACLE10G DATA GUARD--->Physical Standby
    WWDC 2014 Session 205/217 Extension 注意事项
    Android 布局管理器
    软件测试的基本方法(五岁以下儿童)单元测试
    HDU 4896 Minimal Spanning Tree(矩阵高速功率)
    泛泰A860(高通公司8064 cpu 1080p) 拂4.4中国民营recovery TWRP2.7.1.2文本(通过刷第三版)
    Android L SDK -- 一些有趣的新功能
    Jquery在线咨询地址
    项目开发录制两个
  • 原文地址:https://www.cnblogs.com/pipemm/p/12270210.html
Copyright © 2011-2022 走看看