java核心学习(四十) 使用反射生成JDK动态代理

  java.lang.reflect包下提供了一个Proxy类和InvocationHandler接口,用于生成动态代理类和动态代理对象。

一、使用Proxy、InvocationHandler创建动态代理

  这里要注意,在java.net包下也有一个Proxy类,不过这个类是用于设置代理服务器的,莫混淆。。

  Proxy提供了如下两个方法创建动态代理类和动态代理实例:

    

  实际上即使采用第一种方法创建动态代理类,如果程序需要通过该代理类来创建对象,依然需要传入一个InvocationHandler对象,也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。

public class ProxyTest {
    public static void main(String[] args){
        MyInvocationHandler invocationHandler = new MyInvocationHandler();
        invocationHandler.setTarget(new Hero());
        Person hero= (Person) Proxy.newProxyInstance(Hero.class.getClassLoader(),Hero.class.getInterfaces(),invocationHandler);
//        hero.fight();
//        hero.laugh();
        hero.sayHello("Tom");
        hero.work();
    }
}
interface Person{
    void work();
    void sayHello(String name);
}
interface FightAble{
    void fight();
}
class Hero implements Person,FightAble{
    @Override
    public void fight() {
        System.out.println("hero fight");
    }

    @Override
    public void work() {
        System.out.println("hero work");
    }

    @Override
    public void sayHello(String name) {
        System.out.println("hello "+name);
    }
    public void laugh(){
        System.out.println("hero laugh");
    }
}
class MyInvocationHandler implements InvocationHandler{
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("-------正在执行的方法:"+method);
        if(args != null){
            System.out.println("下面是执行该方法传入的实参:");
            for (Object val : args){
                System.out.println(val);
            }
        }

        else {
            System.out.println("调用的方法没有实参");
            method.invoke(target);
        }
        return null;
    }
}

  注意,java动态代理产生的对象一定要用接口引用指向之,这是由于java的动态代理实际上时使用传入的接口类型创建了新的类,所以在上面代码中不可以用Hero类型指向创建的对象,只能由Person或FightAble类型指向之。看源码就可以发现这一点。

二、AOP代理

  AOP(面向切面编程),的一种实现方式就是使用java动态代理。

  在上面的代码中实际上已经实现了AOP,对所有代理对象的无实参方法,在执行方法body之前都先执行System.out.println("调用的方法没有实参");只不过这些代码写在了InvocationHandler中,而像Spring之类的框架会把这一部分代码用设计模式解耦出来,但本质上还是这样子的原理。

转载于:https://www.cnblogs.com/Theshy/p/7764415.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值