天天看点

Spring(九)CGLIB字节码增强

上篇文章说明了jdk动态代理。

在这里说一下cglib动态代理

说明

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

cglib没有接口(通过继承父类) 只有实现类。

采用字节码增强框架cglib,在运行时 创建目标的子类 ,从而对目标类进行增强。

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

目标类

总共实现三个业务

添加用户信息(addUser) 更新用户信息(updateUser) 删除用户信息(deleteUser)

public class UserServiceImpl{

    public void addUser() {
        System.out.println("UserServiceDaoImpl addUser");
    }

    public void updateUser() {
        System.out.println("UserServiceDaoImpl updateUser");
    }


    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