需要说明的地方有:
抽象父类或者接口:定义了这个代理可以代理的方法。比如定义了一个SearchSubject 实现它的子类必须要实现对应的search() 方法。
/**
* 抽象主题,可以进行搜索
*/
public abstract class SearchSubject {
/**
* 可以进行搜索的操作
*/
public abstract void search();
}
真实对象:真实对象也就是具体将要被代理的方法,这个真实对象的方法我们要通过代理类间接的去访问。
众所周知,国内访问不到Google,需要代理才行。
public class Google extends SearchSubject {
@Override
public void search() {
System.out.println("Google 搜索引擎");
}
}
代理类:也就是VPN ,帮助我们访问真实对象 的某些方法,并且还可以做一些增强。比如在访问真实对象之前做一些事情,之后做一些事情。
/**
* VPN 代理
* 静态代理也需要实现抽象主题
*/
public class VPNProxy extends SearchSubject {
/**
* 含有真实主题
*/
private Google google;
@Override
public void search() {
if (null == google) {
google = new Google();
}
this.before();
/**
* 调用真实对象的方法
*/
google.search();
this.after();
}
/**
* 增强方法
*/
public void before() {
System.out.println("VPN 开始执行。。。");
}
public void after() {
System.out.println("VPN 结束执行");
}
}
执行调用代理
VPNProxy proxy = new VPNProxy();
proxy.search();
------------------
VPN 开始执行。。。
Google 搜索引擎
VPN 结束执行
以上就是我们要学习的第一种代理方式:静态代理
动态代理
假设我们还需要代理一个对象呢?比如必应 假设必应搜索我们国内访问不到,必须使用代理的话,是不是又得重新创建两个对象
真实对象必应搜索
代理对象必应搜索的代理
这就不利于我们系统的扩展性,假设有很多需要代理的,那岂不是写一大堆。
因此,动态代理由此而生。
这里我们使用JDK 提供的动态代理
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h){}
ClassLoader 类加载器
interfaces 加载的接口
InvocationHandler 增强处理器以及调用代理的类
创建一个可供实现的搜索接口
/**
* 搜索接口
*/
public interface SearchInterface {
String search();
}
谷歌搜索引擎实现了这个接口,并且将名称作为返回值返回。
public class GoogleSearch implements SearchInterface {
@Override
public String search() {
System.out.println("Google 搜索引擎");
return "Google";
}
}
创建一个搜索增强器,并且创建了两个方法的增强,在调用代理之前和之后,都加入了一些方法。
/**
* 搜索处理器
*/
public class SearchHandler implements InvocationHandler {
private void before() {
System.out.println("handler start");
}
private void after() {
System.out.println("handler stop");
}
private SearchInterface obj;
public SearchHandler(SearchInterface obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.before();
/**
* 执行代理方法
*/
Object result = method.invoke(obj, args);
System.out.println("result=" + result.toString());
this.after();
return result;
}
}
创建一个动态代理工厂,将我们需要代理的接口传入,并且传入接口的处理类,即可实现接口的增强处理。
/**
* 动态代理工厂
*/
public class ProxyFactory {
/**
* 目标对象
*/
private SearchInterface object;
private InvocationHandler handler;
public ProxyFactory(SearchInterface obj, InvocationHandler handler) {
this.object = obj;
this.handler = handler;
}
/**
* 获取代理对象
* @return
*/
public Object getProxyObj() {
ClassLoader classLoader = object.getClass().getClassLoader();
Class<?>[] interfaces = object.getClass().getInterfaces();
return Proxy.newProxyInstance(classLoader, interfaces, handler);
}
}
创建一个具体的接口对象,传入我们的代理工厂,并且将其处理器也同时传入,我们就可以得到一个代理对象。
SearchInterface search = new GoogleSearch();
System.out.println("1id=" + search);
InvocationHandler handler = new SearchHandler(search);
ProxyFactory factory = new ProxyFactory(search, handler);
SearchInterface google = (SearchInterface) factory.getProxyObj();
System.out.println("2id=" + google);
google.search();
-----------------
1id=impl.GoogleSearch@1b6d3586
handler start
result=impl.GoogleSearch@1b6d3586
handler stop
2id=impl.GoogleSearch@1b6d3586
handler start
Google 搜索引擎
result=Google
handler stop
亚马逊测评 www.yisuping.com