动态代理的实现

代理,其实在日常生活中很常见。像房屋的拥有者和中介,明星和经纪人,供货商和代理商。其中中介、经纪人、代理商的工作就可以看做是一种代理。 

在Java软件开发过程中,可能经常会用到代理模式,如Spring的Aop等。代理模式,其实就是控制对实际对象(被代理对象)的访问。而代理模式又分为静态代理和动态代理。(UML图不会画,从网上找来的)

静态代理

在编译期就已经确立好代理对象的就是静态代理。

下面我以明星和经纪人举例,介绍静态代理。

首先,需要定义一个接口,定义一些功能(即方法),代理类和被代理类都需要实现这个接口

// 接口(代理类和被代理类均要实现此接口)
public interface Person {
    void perform();
}

// 被代理类(演员)
public class Actor implements Person{
    private String name;
    public Actor(String name) {
        this.name = name;
    }
    public void perform() {
        System.out.println("我是演员" + this.name +",我要开始表演了。。");
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

// 代理类(经纪人)
public class Agent implements Person{
    // 被代理类(演员)
    private Actor actor;
    public Agent(Actor actor) {
        this.actor = actor;
    }
    public void perform() {
        System.out.println("我是" + actor.getName() + "的经纪人,找演员表演前先联系我洽谈");
        actor.perform();
        System.out.println("我是" + actor.getName() + "经纪人,表演完毕找我结算表演费用");
    }
}

 测试类测试:

// 客户
public class Customer {
    // 开店,详情演员来表演
    public void openStore(Person person){
        person.perform();
    }
}

// 静态代理测试类
public class StaticProxyTest {
    public static void main(String[] args) {
        // 找一个演员,可以真正表演的人
        Actor actor = new Actor("sam");
        // 演员的经纪人
        Person agent = new Agent(actor);
        // 客户有需求:需要找演员表演(找的是经纪人,真正表演的是演员)
        new Customer().openStore(agent);
    }
}

 运行结果:

我是sam的经纪人,找演员表演前先联系我洽谈
我是演员sam,我要开始表演了。。
我是sam经纪人,表演完毕找我结算表演费用

可以看出,演员只需要准备好表演方面的工作,不需要关注那些零碎的跟核心任务无关的事情。这就是代理的优点,专业的事交给专业的人去做。
 

动态代理

动态代理,即代理类是在运行时动态生成的。在Java Api已提供Proxy,InvocationHandler来实现动态代理。

// 代理对象委托类
public class PerformInvocationHandler implements InvocationHandler {
    private Actor actor;

    public PerformInvocationHandler(Actor actor) {
        this.actor = actor;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy name is:"+proxy.getClass().getName()+",method name is:"+method.getName());
        System.out.println("动态代理执行前");
        method.invoke(actor, args);
        System.out.println("动态代理执行后");
        return null;
    }
}


// 动态代理测试类
public class DynamicProxyTest {
    public static void main(String[] args) {
        // 开启代理类打印到本地磁盘
        System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        // 被代理类
        Actor actor = new Actor("新垣结衣");

        // 创建动态代理委托类
        InvocationHandler invocationHandler = new PerformInvocationHandler(actor);
        // 生成代理类(经纪人)
        Person agent = (Person) Proxy.newProxyInstance(actor.getClass().getClassLoader(), actor.getClass().getInterfaces(), invocationHandler);

        // 客户开店请艺人表演
        new Customer().openStore(agent);
    }
}

使用System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"),会将生成的代理类的class文件保存到本地,保存路径为项目/com/sun/proxy/

运行结果:

动态代理执行前
我是演员新垣结衣,我要开始表演了。。
动态代理执行后

至此,就已经实现了代理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值