設計模式——代理模式

知識點:靜態代理和動態代理html

參考博客:https://www.cnblogs.com/daniels/p/8242592.html緩存

                  https://blog.csdn.net/familyshizhouna/article/details/78905997less

一:什麼是代理模式ide

代理模式是給某個對象提供一個代理對象,由代理對象調用原對象的方法,相似咱們生活中的中介,經紀人的角色,本人不直接去作,找一我的代替咱們去作一些事情。測試

二:使用代理模式的好處this

a.中介隔離做用:當咱們不想直接調用一個對象時,代理對象能夠起一箇中介隔離的做用,被代理對象和代理對象都實現相同的接口spa

b.遵循開閉原則:咱們能夠經過代理類,在被代理類功能先後,加入一些公共服務,好比緩存,日誌等,而不用修改原被代理類.net

三:代理模式的分類代理

 按建立代理的時間分類能夠分爲:靜態代理和動態代理日誌

   靜態代理是代碼建立後編譯,運行以前,代理類的.class文件就已經建立了;

  動態代理:是在程序運行時,經過反射機制動態建立代理對象的(另外一篇博客簡略地介紹Java中的反射:https://www.cnblogs.com/shuaifing/p/10863645.html)

(1)靜態代理

//代理模式(靜態代理)
//測試類
public class StaticProxy {
public static void main(String[] args) {
Object obj=new ProxyObject();
obj.action();
}
}
//公共接口
interface Object{
void action();
}
//代理類
class ProxyObject implements Object{
Object obj;
public ProxyObject(){
System.out.println("代理類構造方法建立被代理類");
obj=new ObjectImp();
}
@Override
public void action() {
System.out.println("代理類執行被代理類中的方法");
obj.action();
}
}
//被代理類
class ObjectImp implements Object{
@Override
public void action() {
System.out.println("被代理類輸出的內容!");
}
}
運行結果:

(2)動態代理

當有多個類要代理的話,手動建立多個代理對象比較麻煩,代碼冗餘,動態產生代理對象的話,代碼更加靈活,方便

//動態代理,反射是動態語言的關鍵
//測試類
public class DynamicProxy {
public static void main(String[] args) {
//1.被代理類的對象
RealSubject realSubject=new RealSubject();
//2.建立一個實現InvocationHandler接口類的對象
MyInvocationHandler handler=new MyInvocationHandler();
//3.調用blind()方法,動態返回一個實現了跟被代理類所實現接口的代理對象
Object obj=handler.blind(realSubject);
Subject subject=(Subject) obj;//subject是代理類對象
subject.action();//代理類對象調用action(),會轉到對InvocationHandler接口實現類的invoke()方法調用


//增長另外一個 ObjectImp的被代理對象,返回相應的代理對象
ObjectImp objIml=new ObjectImp();
com.kdgc.interfacetest.Object proxyObject= (com.kdgc.interfacetest.Object)handler.blind(objIml);
proxyObject.action();
}
}
//公共接口
interface Subject{
void action();
}
//被代理類
class RealSubject implements Subject{
@Override
public void action() {
System.out.println("被代理類要執行的方法!");
}
}
class MyInvocationHandler implements InvocationHandler{
Object obj;//實現了接口的被代理對象的聲明

//1.給被代理對象實例化 2.返回一個代理類的對象
public Object blind(Object obj){
this.obj=obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
//當經過代理類的對象發起對被重寫方法的調用時,會轉化爲對下面的invoke方法的調用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object val=method.invoke(obj,args);
return val;
}
}

運行結果:

 (3)補充:動態代理與AOP

在固定的代碼的位置,動態地調用不一樣對象的方法

   //測試類

public class AOPTest {
public static void main(String[] args) {
Man man = new Man();
Person person = (Person) MyProxy.getProxyInstance(man);
person.drink();
person.eat();
}
}
//公共接口
interface Person{
void eat();
void drink();
}
//被代理類
class Man implements Person{
@Override
public void eat() {
System.out.println("吃東西!");
}
@Override
public void drink() {
System.out.println("喝水!");
}
}
//固定的方法
class ChangelessMethodUtil{
public void method1(){
System.out.println("===========方法1==========");
}
public void method2(){
System.out.println("============方法2===========");
}
}
class MyInvocationHanlder implements InvocationHandler{
Object obj;//代理類的聲明
public void setObject(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ChangelessMethodUtil changelessMethodUtil=new ChangelessMethodUtil();
changelessMethodUtil.method1();

method.invoke(obj,args);

changelessMethodUtil.method2();
return null;
}
}
class MyProxy{
//動態建立一個代理類的對象
public static Object getProxyInstance(Object obj){
MyInvocationHanlder hanlder=new MyInvocationHanlder();
hanlder.setObject(obj);

return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),hanlder);
}
}

運行結果:

相關文章
相關標籤/搜索