• JDK动态代理


    静态代理与动态代理的区别

    • 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件

    • 动态代理是在运行时动态生成的,即编译完成之后没有实际的class文件,而是在运行时动态生成类字节码 ,并加载到JVM中

    • 动态代理分为:JDK动态代理和CGLib动态代理 【二者具体的区别在后面章节进行介绍】

    JDK动态代理

    JDK动态代理又称为接口代理,顾名思义它只能代理实现了接口的类,它是利用反射机制生成一个实现代理接口的类(这个类看不见,摸不着,在jvm内存中有这个类),在调用具体方法前调用InvokeHandler来处理。核心是实现InvokeHandler接口,使用invoke()方法进行面向切面的处理,调用相应的通知

    • 接口类
    public interface UserService {
        void select();
        void update();
    }
    
    • 目标类
    public class UserServiceImpl implements UserService{
        @Override
        public void select() {
            System.out.println("查询 selectById");
        }
    
        @Override
        public void update() {
            System.out.println("更新 update");
        }
    }
    
    • 代理类模板 注意这里不是代理类,因为动态代理类是调用时由JVM动态生成的,所以这里只是代理类的一个模板
    public class LogHandler implements InvocationHandler {
        private Object target; //被代理的对象,方法的实际执行者
        public LogHandler(Object target){
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            Object invoke = method.invoke(target, args);
            after();
            return invoke;
        }
        private void before(){
            System.out.println("方法调用前");
        }
        private void after(){
            System.out.println("方法调用后");
        }
    }
    
    • 测试
    public class Client {
        public static void main(String[] args) {
            UserService userServiceImp = new UserServiceImpl(); //被代理的对象
            //获取类加载器
            ClassLoader classLoader = userServiceImp.getClass().getClassLoader();
            //获取所有接口的class
            Class[] interfaces = userServiceImp.getClass().getInterfaces();
            //创建一个将传给代理类的调用请求处理器,处理所有的代理对象上的方法调用
            //这里创建的是一个自定义的日志处理器,需要传入实际的执行对象UserServiceImpl
            LogHandler logHandler = new LogHandler(userServiceImp);
             //创建具体的代理类
            UserService proxy = (UserService) Proxy.newProxyInstance(classLoader, interfaces, logHandler);
            proxy.update();
            proxy.select();
        }
    }
    
    方法调用前
    更新 update
    方法调用后
    方法调用前
    查询 selectById
    方法调用后
    
  • 相关阅读:
    汇编语言之第三章寄存器(内存访问)
    汇编语言之第一章基础知识
    汇编语言之实验二
    python爬虫——利用BeautifulSoup4爬取糗事百科的段子
    电子表格拼接助手
    龙龙背作文V1.0——考研英语作文专项训练软件
    龙龙记单词V1.1——更美,更多,更强
    书签小助手V1.0发布了
    龙龙排短文V1.0——考研英语排序题专项训练软件
    保定市公交换乘离线查询系统
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/14279643.html
Copyright © 2020-2023  润新知