• SpringAOP之CGLIB字节码增强


    SpringAOP的基础原理就是动态代理

    有两种实现方式:
    1)jdk动态代理

    2)cglib动态代理

    jdk动态代理和cglib动态代理的区别在于:

    cglib没有接口(通过继承父类) 只有实现类。 
    采用字节码增强框架cglib,在运行时 创建目标的子类 ,从而对目标类进行增强。

    简单来说就是把目标类当jdk动态代理里的接口使用,把运行时创建的目标类的子类当jdk动态代理里的目标类使用。

    下面通过一个案例来说明CGLIB动态代理 

    目标类 ,实现了三个业务

    public class UserServiceImpl{
    
      //添加用户信息(addUser)
    public void addUser() { System.out.println("UserServiceDaoImpl addUser"); }
      //更新用户信息(updateUser)
    public void updateUser() { System.out.println("UserServiceDaoImpl updateUser"); }   //删除用户信息(deleteUser) public void deleteUser() { System.out.println("UserServiceDaoImpl deleteUser"); } }

    切面类 ,用于增强功能的类,里面就是具体的功能方法(通知)

    public class MyAspect {
        //前方法
        public void before(){
            System.out.println("cglib_before");
    
        }
        //后方法
        public void after(){
            System.out.println("cglib_after");
        }
    }   

    工厂类 

    工厂类步骤如下: 
    1.目标类 
    2.切面类 
    3.代理类 
    3.1 核心类 
    3.2确定父类 
    3.3设置回调函数 
    而在设置回调函数里面和jdk动态代理类似 
    设置回调函数 MethodInterceptor接口等效于jdk invocationHandler接口 
    intercept()等效于jdk invoke() 
    intercept参数1 ,参数2,参数3 和invoke三个参数一样 
    参数4,methodProxy 方法代理 
    可以使用methodProxy.invokeSuper(proxy, args);来执行父类的方法

    public class MyProxyFactory {
        public static Object createUserService() {
            //目标类
            final UserServiceImpl userService = new UserServiceImpl();
            //切面类
            final MyAspect myAspect = new MyAspect();
            //代理类 采用cglib 底层创建目标的子类
            //核心类
            Enhancer enhancer=new Enhancer();
            //确定父类
            enhancer.setSuperclass(UserServiceImpl.class);
            /*
             *  设置回调函数 MethodInterceptor接口等效于jdk invocationHandler接口
             *  intercept()等效于jdk invoke()
             *  参数1 ,参数2,参数3 和invoke三个参数一样
             *  参数4,methodProxy  方法代理
             */
            enhancer.setCallback(new MethodInterceptor() {
    
                @Override
                public Object intercept(Object proxy, Method method, Object[] args,
                        MethodProxy methodProxy) throws Throwable {
                    //前方法
                    myAspect.before();
                    //执行目标类的方法
                    Object obj=method.invoke(userService, args);
                    //后方法
                    myAspect.after();
                    return obj;
                }
            });
            Object proxy=enhancer.create();
            return proxy;
        }
    }

    运行结果: 

    https://blog.csdn.net/su20145104009/article/details/54234607

  • 相关阅读:
    电商网站测试总结
    web测试总结—用户体验
    测试用例的常用方法
    linux系统中如何查看日志 (常用命令)
    web与app测试的区别
    Json模块dumps、loads、dump、load函数介绍
    postman—集成到jenkins
    Postman—命令执行脚本及生成报告
    Postman—测试脚本
    Postman—前置请求脚本
  • 原文地址:https://www.cnblogs.com/xdyixia/p/9361143.html
Copyright © 2020-2023  润新知