java 中jdk动态代理和CGLIB动态代理


jdk的动态代理是需要目标接口的,而spring提供的cglib代理是不需要目标接口的。

1、jdk动态代理实践过程

定义接口

public interface Person {
    public void rentHouse();
    public void rentHouse(String name);
}

定义接口实现类

public class Renter implements Person{
    @Override
    public void rentHouse() {
        System.out.println("租房");
    }
    @Override
    public void rentHouse(String name) {
        System.out.println("租房"+name);
    }
}

定义代理类行为(类似于spring中aop的各种通知)

public class RenterInvocationHandler<T> implements InvocationHandler {
    // 被代理类,从构造方法传入
    private T target;
    public RenterInvocationHandler(T target) {
        this.target = target;
    }
    /**
     * @param proxy  代表动态代理对象
     * @param method 代表正在执行的方法
     * @param args   代表调用目标方法时传入的实参
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("租客和中介交流");
        // 调用
        Object result = method.invoke(target, args);
        System.out.println("租房结束");
        return result;
    }
}

代理测试

public static void main(String[] args) {
        // 被代理类
        Person renter = new Renter();

        RenterInvocationHandler<Person> renterInvocationHandler = new RenterInvocationHandler<>(renter);

        // 传入类加载器,代理类需要实现的接口,handler
        Person renterProxy = (Person)Proxy.newProxyInstance(Person.class.getClassLoader(),new Class<?>[]{Person.class},renterInvocationHandler);

        renterProxy.rentHouse();
        System.out.println();
        renterProxy.rentHouse("越美国际");
    }

打印结果

租客和中介交流
租房
租房结束

租客和中介交流
租房越美国际
租房结束

2、CGLIB动态代理实践过程

创建被代理类

public class Renter2 {
    public void rentHouse() {
        System.out.println("租房");
    }
    public void rentHouse(String name) {
        System.out.println("租房"+name);
    }
}

创建代理工厂

/**
 * 该类用于生成目标类的代理对象,并且指定增强的内容,是通过重写intercept拦截方法
 * @param <T>
 */
public class ProxyFactory<T> implements MethodInterceptor {
    // cglib工具类
    private Enhancer en = new Enhancer();
    // 被代理对象
    private T target;

    public ProxyFactory(T target) {
        this.target = target;
    }

    /**
     * 返回代理类 proxy
     * @param clazz
     * @return
     */
    public T getProxyInstance(Class<?> clazz){
        // 父类
        en.setSuperclass(clazz);
        // 回调类方法所在类
        en.setCallback(this);
        return (T)en.create();
    }

    /**
     * 拦截方法,增强类
     * @param obj
     * @param method 被代理类的method
     * @param args 方法参数
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("中介和租客交流");
        Object result = method.invoke(target,args);
        System.out.println("租房结束");
        return result;
    }

    /**
     * 测试过程
     * @param args
     */
    public static void main(String[] args) {
        ProxyFactory<Renter2> renter2ProxyFactory = new ProxyFactory<>(new Renter2());
        Renter2 proxyInstance = renter2ProxyFactory.getProxyInstance(Renter2.class);
        
        proxyInstance.rentHouse();
        System.out.println();
        proxyInstance.rentHouse("越美国际");

    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值