在Java中实现代理模式有两种常见的方式:静态代理和动态代理。
- 静态代理: 静态代理是指在编译时就已经确定了代理类和被代理类的关系,代理类和被代理类实现了相同的接口,代理类中持有被代理类的对象,在代理类中调用被代理类的方法,并在方法前后加入额外的逻辑。以下是一个简单的静态代理示例:
//接口
interfaceImage{
voiddisplay();
}
//被代理类
classRealImageimplementsImage{
privateStringfileName;
publicRealImage(StringfileName){
this.fileName=fileName;
loadFromDisk();
}
privatevoidloadFromDisk(){
System.out.println("Loadingimagefromdisk:"+fileName);
}
publicvoiddisplay(){
System.out.println("Displayingimage:"+fileName);
}
}
//代理类
classProxyImageimplementsImage{
privateRealImagerealImage;
privateStringfileName;
publicProxyImage(StringfileName){
this.fileName=fileName;
}
publicvoiddisplay(){
if(realImage==null){
realImage=newRealImage(fileName);
}
realImage.display();
}
}
//使用示例
publicclassMain{
publicstaticvoidmain(String[]args){
Imageimage=newProxyImage("test.jpg");
image.display();
}
}
java.lang.reflect.Proxy
类和java.lang.reflect.InvocationHandler
接口来实现。以下是一个简单的动态代理示例:importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
//接口
interfaceImage{
voiddisplay();
}
//被代理类
classRealImageimplementsImage{
privateStringfileName;
publicRealImage(StringfileName){
this.fileName=fileName;
loadFromDisk();
}
privatevoidloadFromDisk(){
System.out.println("Loadingimagefromdisk:"+fileName);
}
publicvoiddisplay(){
System.out.println("Displayingimage:"+fileName);
}
}
//InvocationHandler实现
classImageInvocationHandlerimplementsInvocationHandler{
privateImageimage;
publicImageInvocationHandler(Imageimage){
this.image=image;
}
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
System.out.println("Beforemethod"+method.getName());
Objectresult=method.invoke(image,args);
System.out.println("Aftermethod"+method.getName());
returnresult;
}
}
//使用示例
publicclassMain{
publicstaticvoidmain(String[]args){
ImagerealImage=newRealImage("test.jpg");
ImagedynamicProxy=(Image)Proxy.newProxyInstance(
realImage.getClass().getClassLoader(),
realImage.getClass().getInterfaces(),
newImageInvocationHandler(realImage));
dynamicProxy.display();
}
}
无论是静态代理还是动态代理,代理类都可以在被代理类的方法前后加入额外的逻辑,实现对被代理类的控制和增强。动态代理相对于静态代理的优势在于可以简化代理类的编写,同时一个代理类可以代理多个接口。