本章按以下顺序讲解Java代理:
1、什么是代理?为什么要用代理?
2、初步认识代理并举例实现
3、总结
****************************************************************************************************************************************************************
1、 代理模式:为一个对象提供一个代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。很常用的例子如监控器等。
2、 代理模式一般涉及到的角色有:抽象角色、代理角色、真实角色
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。
同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
代码举例
(1)抽象角色:接口
public interface Greet {
public void sayHello(String name);
public void goodBye(String name);
}
(2)真实角色:实现类
public class GreetImpl implements Greet{
@Override
public void sayHello(String name) {
System.out.println("hello "+name);
}
@Override
public void goodBye(String name) {
System.out.println("good bye "+name);
}
}
(3)代理角色:代理类
public classSimpleProxy implements Greet {
private Greet greet;
public SimpleProxy(Greetgreet) {
this.greet = greet;
}
@Override
public void sayHello(String name) {
System.out.println("--before method sayHello");
greet.sayHello(name);
System.out.println("--after method sayHello");
}
@Override
public void goodBye(String name) {
System.out.println("--before method goodBye");
greet.goodBye(name);
System.out.println("--after method goodBye");
}
}
测试代理代码:
public static void main(String[] args) {
Greetgreet = new SimpleProxy(newGreetImpl());//生成代理
greet.sayHello("Mr Ling");
greet.goodBye("Mr Ling");
}
测试结果:
--before method sayHello
hello Mr Ling
--after method sayHello
--before method goodBye
good bye Mr Ling
--after method goodBye
由以上代码可以看出,客户实际需要调用的是GreetImpl类的方法,现在用SimpleProxy来代理,同样达到目的,同时还封装了方法,可以处理一些问题。
3、总结
在代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。这一点与装饰者不同,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已。
用途:代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
缺点:以上我们实现代理的方式称为静态代理,由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。通过观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成,总的来说缺点就是静态代理导致类膨胀。
动态代理正好解决了这些问题,请关注,本博客会持续更新。