zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    jQuery选择器
    asp.net 操作 excel 出现 class 组件错误 或 打开文件错误
    [转]Win7、Windows Server 2008下无法在Windows Service中打开一个已经存在的Excel 2007文件问题的解决方案
    Microsoft Excel 不能访问文件“ 文件名称或路径不存在。 • 文件正被其他程序使用。 • 您正要保存的工作簿与当前打开的工作簿同名。
    页面打印 css
    如何在excel数据透视表的顶部显示列总计
    asp中javascript或jquery如果在body中 且需要页面元素 则需要放在最后
    sqlserver游标使用
    excel 冻结多行
    Request.Form("cardno").Item(y) 的count总是为0
  • 原文地址:https://www.cnblogs.com/xdyixia/p/9361143.html
Copyright © 2011-2022 走看看