Java动态代理

代理模式的目的

  • 需要隐藏委托者,使调用者只和代理打交道
  • 不需要隐藏委托者,只需要在调用前后增加处理逻辑。

Java中规定,动态代理的对象必须要有实现一个接口,因为要动态创建这个接口的实现类。

在JDK1.5之后提供了"java.lang.reflect.Proxy",通过"Proxy"类的newProxyInstance静态方法创建一个接口的代理对象,这个代理对象可以调用接口的方法。

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

newProxyInstance方法返回一个代理对象,这个方法有3个参数:

  • ClassLoader 指明接口类装载器,
  • Class<?>[] 指明代理对象的接口,
  • InvocationHandler 指明代理对象要做的事情。
//歌星接口
public interface StarMan {
    String sing(String song);
}

//歌星A
public class StarA implements StarMan {
    public void sing(String song){
        System.out.println("歌星A演唱"+song);
    }
}

//歌星B
public class StarB implements StarMan {
    public void sing(String song){
        System.out.println("歌星B演唱"+song);
    }
}

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

public class ProxyOrg {
    //联系歌星经纪人
    public static StarMan getStarManProxy(String starName) {
        Class<?>[] interfaces={StarMan.class};
        return (StarMan) Proxy.newProxyInstance(StarMan.class.getClassLoader(), interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result=null;

                if (method.getName().equals("sing")) {
                    System.out.println("我是经纪人");

                    StarMan starMan = null;

                    //经纪人在此处根据要求去联系歌星
                    if(starName.equals("歌星A")){
                        starMan = new StarA();
                    }else if(starName.equals("歌星B")){
                        starMan = new StarB();
                    }

                    if(starMan!=null){
                        System.out.println("我已联系到歌星,请歌星演唱");
                        result = method.invoke(starMan, args);
                    }else{
                        System.out.println("我联系不到歌星");
                    }
                }

                return result;
            }
        });
    }
}


public class Main {
    public static void main(String[] args) {
        //请经纪人联系歌星A
        StarMan p = ProxyOrg.getStarManProxy("歌星A");
        p.sing("歌曲A");

        //请经纪人联系歌星B
        p = ProxyOrg.getStarManProxy("歌星B");
        p.sing("歌曲B");
    }
}

CGLIB动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行 修改和动态生成。CGLIB通过继承方式实现代理,在子类中采用方法拦截的技术拦截所有父类方法的调 用并顺势织入横切逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值