广州最新政策,seo技术培训唐山,南通住房和城乡建设局网站,wordpress子目录建站1#xff0c;代理模式
代理模式给某一个对象提供一个代理对象#xff0c;并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
代理模式的目的#xff1a;
#xff08;1#xff09;通过引入代理对象的方式来间接访问目标对象#xff0c;防…1代理模式
代理模式给某一个对象提供一个代理对象并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
代理模式的目的
1通过引入代理对象的方式来间接访问目标对象防止直接访问目标对象给系统带来的不必要复杂性
2通过代理对象对访问进行控制
代理模式一般会有三个角色
抽象角色指代理角色和真实角色对外提供的公共方法一般为一个接口。
真实角色需要实现抽象角色接口定义了真实角色所要实现的业务逻辑以便供代理角色调用。也就是真正的业务逻辑在此。
代理角色需要实现抽象角色接口是真实角色的代理通过真实角色的业务逻辑方法来实现抽象方法并可以附加自己的操作。将统一的流程控制都放到代理角色中处理。
2静态代理
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。一般来说被代理对象和代理对象是一对一的关系当然一个代理对象对应多个被代理对象也是可以的。
比如我要卖房子但是我不会自己去卖我会先找到中介让中介去卖。
这里的抽象角色就是卖房子。
真实角色就是我卖房子。
代理角色就是中介卖房子。
新建一个抽象接口
public interface SailRoom {//卖房子void sailRoom();
}
创建真实的卖房子的对象
public class Me implements SailRoom{Overridepublic void sailRoom() {System.out.println(sail my room);}
}
创建一个中介代理类
public class RoomProxy implements SailRoom {private Me me;public RoomProxy(Me me) {this.me me;}private void before(){System.out.println(before sail room);}private void after(){System.out.println(after sail room);}Overridepublic void sailRoom() {before();me.sailRoom();after();}
}
在应用时这么使用
RoomProxy proxy new RoomProxy(new Me());
proxy.sailRoom();
那我如果要想再卖一个二手苹果手机那我找中介就不行了那我只能再去创建一个新的卖二手手机代理去去卖二手手机。
创建一个新的卖手机的接口
public interface SailPhone {/** 卖手机* */void sailPhone();
}
实现这个接口
public class Me implements SailRoom,SailPhone{Overridepublic void sailRoom() {System.out.println(sail my room);}Overridepublic void sailPhone() {System.out.println(sail my phone);}
} 创建一个卖手机的代理类
public class PhoneProxy implements SailPhone{private Me me;private void before(){System.out.println(before sail phone);}private void after(){System.out.println(after sail phone);}Overridepublic void sailPhone() {before();me.sailPhone();after();}
}
使用时
public static void main(String[] args) {Me me new Me();RoomProxy proxy new RoomProxy(me);PhoneProxy phoneProxy new PhoneProxy(me);proxy.sailRoom();phoneProxy.sailPhone();
}
输出
before sail room
sail my room
after sail room
before sail phone
sail my phone
after sail phone
从上面可以很明显的看出静态代理模式的缺点
1如果有多个类需要代理那么就需要创建多个代理类分别代理目标对象工作量较大不利于维护。
2当接口的方法增加或修改的时候很多类都需要修改。因为目标类和代理类都实现了相同的接口
3动态代理
上面那个案例用动态代理怎么实现呢
下面我们用jdk的动态代理来实现
先创建我们的动态代理类
public class SailProxy implements InvocationHandler {private Object object;public SailProxy(Object object) {this.object object;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(do before);Object invoke method.invoke(object, args);System.out.println(do after);return invoke;}
}
在使用时
public class Test {public static void main(String[] args) {Me me new Me();SailProxy sailProxy new SailProxy(me);Object o Proxy.newProxyInstance(me.getClass().getClassLoader(), new Class[]{SailRoom.class,SailPhone.class}, sailProxy);SailRoom sailRoom (SailRoom) o;sailRoom.sailRoom();SailPhone sailPhone (SailPhone) o;sailPhone.sailPhone();}
}
输出
do before
sail my room
do after
do before
sail my phone
do after
这样我们就实现了一劳永逸只创建一个代理类就可以代理无数个接口。没错是接口JDK的实现的动态代理它代理的只是接口。
下面我们就来详细讲解一下上个案例。
首先在SailProxy中我们实现了InvocationHandler这个接口实现了接口的invoke方法。
Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(do before);Object invoke method.invoke(object, args);System.out.println(do after);return invoke;
}
其中 参数一Object proxy 与
Object o Proxy.newProxyInstance(me.getClass().getClassLoader(), new Class[]{SailRoom.class,SailPhone.class}, sailProxy);
的返回值Object o是一个对象都是代表的传入的 new Class[]{SailRoom.class,SailPhone.class}
的接口对象。可以强转为SailRoom也可以强转为SailPhone。
接下来看第二个参数Method method它代表的是你调用的接口的方法可以是sailRoom(),也可以是sailPhone()。
第三个参数Object[] args就是接口方法的参数。
当你调用sailRoom.sailRoom()时就会回调到invoke方法里面调用
此时的method就是sailRoom()object就是Me这个实际的角色args就是方法参数此处为空。
注意
1jdk实现的动态代理只能代理接口不能代理类。
2动态代理生成的代理类并不像普通类那样通过Javac生成class文件存放在磁盘中他并不是一个真正的class文件它只是存放在内存中。