动态代理:JDK和cglib

1 JDK自带的动态代理

1.1 JDK动态代理要求

  • 被代理对象需要实现接口
  • JDK功能自带,不需要导包

1.2 相关代码

1.2.1 代理对象代码
package com.zgd.learn.spring.proxy.jdk;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

/**
 * JDK的动态代理:需要有接口
 */
public class ObjectProxy implements InvocationHandler
{
	/**
     * 被代理对象,通过构造传入
     */
    private Object object;

    public ObjectProxy(Object object)
    {
        this.object = object;
    }

    /**
     * 获取代理对象
     */
    public Object createProxy()
    {
    	// 三个参数
    	// 第一个参数:被代理对象的类加载器
    	// 第二个参数:被代理对象的父接口
    	// 第三个参数:代理的执行逻辑Handler
        Object proxy = Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),
                this);
        return proxy;
    }

    /**
     * 代理执行逻辑
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("执行前处理...");
        Object result = method.invoke(object, args);
        System.out.println("执行后处理...");
        return result;
    }
}
1.2.2 被代理对象代码
public class UserDaoImpl implements UserDao
{
    @Override
    public void save()
    {
        System.out.println("UserDaoImpl save()");
    }
}
1.2.3 测试类
    @Test
    public void testObjcetProxy()
    {
        UserDao userDao = new UserDaoImpl();
        UserDao proxy = (UserDao) new ObjectProxy(userDao).createProxy();
        proxy.save();
    }
1.2.4 运行结果
执行前处理...
UserDaoImpl save()
执行后处理...

2 cglib动态代理

2.1 cglib要求

  • 可以代理没有实现接口的类,实质是产生一个被代理类的子类,所以被代理类和方法不能有final修饰
  • 需要导包:cglib.jar
  • final修饰的类,不能被动态代理,会产生java.lang.IllegalArgumentException: Cannot subclass final class
  • 代理非final类,执行final方法,则不会产生代理效果,但不抛异常

2.2 相关代码

2.2.1 cglib的代理代码
package com.zgd.learn.spring.proxy.cglib;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor
{
    /**
     * 被代理对象,通过构造传入
     */
    public Object object;

    public CglibProxy(Object object)
    {
        this.object = object;
    }

    public Object creatProxy()
    {
        // cglib的核心类对象
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(object.getClass());
        // 设置回调
        enhancer.setCallback(this);
        // 创建代理对象
        Object proxy = enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
    {
        System.out.println("执行前处理...");
        Object result = methodProxy.invoke(object, args);
        System.out.println("执行后处理...");
        return result;
    }
}

2.2.2 被代理对象代码
public class UserService
{
    public void save()
    {
        System.out.println("UserService save()");
    }
}

2.2.3 测试类
    @Test
    public void testCglibProxy()
    {
        UserService userService = new UserService();
        UserService proxy = (UserService) new CglibProxy(userService).createProxy();
        proxy.save();
    }
2.2.4 运行结果
执行前处理...
UserService save()
执行后处理...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值