jdk动态代理

接口和实现

package com.company.proxy;

public interface Fruit {
    void add();
    void add2();
}





package com.company.proxy;

public class FruitImpl implements Fruit {
    @Override
    public void add() {
        System.out.println("添加水果");
    }
    @Override
    public void add2() {
        System.out.println("添加水果2");
    }
}

核心类 InvocationHandler

package com.company.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("pre ......");
        Object o = method.invoke(target, args);
        System.out.println("after ......");
        return o;
    }
}

实现代理

public class FruitProxy {
    public static void main(String[] args) {
        FruitImpl fruit = new FruitImpl();
        MyInvocationHandler handler = new MyInvocationHandler(fruit);

        Object o = Proxy.newProxyInstance(fruit.getClass().getClassLoader(), fruit.getClass().getInterfaces(), handler);
        Fruit f = (Fruit) o;
        f.add();
        f.add2();
    }
}

 

 

内部类实现:

public class FruitProxy {
    public static void main(String[] args) {
        Object o = Proxy.newProxyInstance(FruitImpl.class.getClassLoader(), FruitImpl.class.getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //根据方法名代理
                        if (method.getName().equals("add")) {
                            System.out.println("pre ......");
                            method.invoke(new FruitImpl(), args);
                            System.out.println("after ......");
                        }else {
                            method.invoke(new FruitImpl(), args);
                        }
                        return null;
                    }
                });

//        Fruit f = (Fruit) o;
        ((Fruit) o).add();
        ((Fruit) o).add2();
    }
}

 

只增强add() 方法;

 

利用java反射和动态代理的技术 应用十分广泛;

使用JDK动态代理有一个很大的限制,就是它要求目标类必须实现了对应方法的接口,它只能为接口创建代理实例。我们在上文测试类中的Proxy的newProxyInstance方法中可以看到,该方法第二个参数便是目标类的接口。如果该类没有实现接口,这就要靠cglib动态代理了。

CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势植入横切逻辑。

 

 

CGLib动态代理能代理类和接口,但是不能代理final类,也是有一定局限性。

JDK动态代理和CGLib动态代理都是运行时增强,通过将横切代码植入代理类的方式增强。与此不同的是AspectJ,它能够在通过特殊的编译器在编译时期将横切代码植入增强,这样的增强处理在运行时候更有优势,因为JDK动态代理和CGLib动态代理每次运行都需要增强。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值