Cglib代理

目录

Cglib代理

Cglib代理适用场景

注意事项


Cglib代理

子类代理,在内存中构建一个子类对象从而实现对目标对象的扩展。

Cglib代理适用场景

有一个目标对象,但是没有接口

import org.springframework.cglib.proxy.Enhancer;
//代理工厂提供获取代理的方法

public class CglibProxyFactory {
    public static <T> T getProxyInstance(T t) {
        //使用Cglib生成子类代理步骤
        Enhancer enhancer = new Enhancer();
        //指定生成哪个类的代理
        enhancer.setSuperclass(t.getClass());
        //设置回调(就是想当于设置调用目标对象方法时会进入MyMethodInterceptor的intercept方法)
        enhancer.setCallback(new MyMethodInterceptor());
        //创建子类代理对象
        return (T) enhancer.create();
    }
}

//新建增强类实现 MethodInterceptor
public class MyMethodInterceptor implements MethodInterceptor {
    /**
     *前三个参数和InvocationHandler里面的invoke方法参数一样
     * @param o:生成的Cglib代理对象
     * @param method:被拦截的方法
     * @param objects:被拦截的方法的参数
     * @param methodProxy:表示可以触发父类的方法的方法代理对象
     * @return
     * @throws Throwable
     */
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开始事务---》");
        //是Cglib代理
        System.out.println(o.getClass());
        //父类是目标对象,即Cglib的代理默认都继承自目标对象,是目标对象的子类
        System.out.println(o.getClass().getSuperclass());
        //指调用o的父类的方法,o的父类即是代理对象的父类,即被代理的对象,即目标对象。
        //调用被代理对象的方法
        Object obj = methodProxy.invokeSuper(o, objects);
        System.out.println("提交事务---》");
        return obj;
    }
}

测试:

public class TestCglib {
    public static void main(String[] args) {
        UserService userService = new UserService();
        UserService proxyInstance = CglibProxyFactory.getProxyInstance(userService);
        proxyInstance.saveUser();
    }
}

运行结果:

注意事项

  1. 有final修饰的类不可以被代理(因为不能有子类)
  2. final或static修饰的方法不可以被拦截

有final修饰的类

public final class UserService {
    public void saveUser() {
        System.out.println("保存数据---》" + new User());
    }
}

运行上面测试代码,报如下异常

有final或static修饰的方法:

public class UserService {
    public final void saveUser() {
        System.out.println("保存数据---》" + new User());
    }
}
public class UserService {
    public static void saveUser() {
        System.out.println("保存数据---》" + new User());
    }
}

 

运行上面测试代码,结果并没有被拦截:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值