Spring spring的cglib动态代理

本文深入探讨了CGLIB动态代理的原理与应用,详细解释了如何通过CGLIB生成目标类的子类并重写其方法,适用于未实现接口的类。同时,对比了CGLIB与JDK动态代理的优劣,提供了具体的代码示例和Spring框架中的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.cglib动态代理

1.CGLIB代理:
    1,CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
    2,要求类不能是final的,要拦截的方法要是非final、非static、非private的。
    3,动态代理的最小单位是类(所有类中的方法都会被处理);

2.在Spring中cglib和jdk代理选择:
  若目标对象实现了若干接口,Spring就会使用JDK动态代理。
  若目标对象没有实现任何接口,Spring就使用CGLIB库生成目标对象的子类。
  对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统,也更符合面向接口编程规。
  cglib和javassist代理的机制都是一样的,都是通过继承实现的.

二.代码示例(Service接口及其实现类,请看上一篇jdk动态代理博文)

 cglib动态代理类:


// 主要针对于类,采用继承于父类
@SuppressWarnings("all")
@Component("cglibProxy")
public class TransactionManagerCallBack implements  org.springframework.cglib.proxy.InvocationHandler {
    @Autowired
    @Qualifier("target")
    private Object target; //真实对象(被代理的对象):在此处指的是EmployeeServiceImpl
    @Autowired
    private TransactionManager txManager;

    // 创建一个代理对象
    public <T>T getProxyObject(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass()); // 设置继承于哪一个父类
        enhancer.setCallback(this); // this是InvocationHandler 增强的对象
        return (T)enhancer.create();  // 创建一个代理对象
    }

    // 在真实对象上做增强操作
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object obj = null;
        txManager.begin();
        try {
            obj = method.invoke(target, args); // 真实对象中的方法
            txManager.commit();
        } catch (Exception e) {
            txManager.rollback();
            e.printStackTrace();
        }

        return obj;
    }
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        ">

    <!-- 解析autowired,resource,qualifier-->
    <context:annotation-config />
    <!--去哪些包下面去扫描组件-->
    <context:component-scan base-package="com.shenzhenair.day02.common" />
    <context:component-scan base-package="com.shenzhenair.day02.cglib_proxy" />


</beans>

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/shenzhenair/day02/cglib_proxy/cglibProxy.xml")
public class cglibProxyTest {
    @Autowired
    @Qualifier("cglibProxy")
    private TransactionManagerCallBack callback;

     //com.sun.proxy.$Proxy15
    @Test
    public void testSave(){
        // 获得代理对象
        // com.shenzhenair.day02.common.service.impl.EmployeeServiceImpl$$EnhancerByCGLIB$$820d8dfb
        IEmployeeService service = callback.getProxyObject();
        System.out.println(service.getClass());
        service.save(new Employee());
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值