代理模式介绍
- 23种常用的面向对象软件的设计模式之一
- 为目标对象提供另外一种访问方式,通过访问代理对象来间接访问目标对象。
- 优点:
(1).职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
(3).高扩展性 - 结构:
- 一个是真正的你要访问的对象(目标类)
- 另一个是代理对象(代理类)
- 真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。
- 代理模式又分为静态代理和动态代理
静态代理
- 使用静态代理需要定义三个类,定义一个接口或父类,让代理对象和真实对象同时实现或继承父类。代理对象中维护一个被代理对象,并追加额外的功能。
- 优点:可以在不修改目标对象的情况下追加新的功能。
- 缺点:当接口方法中添加新的方法之后,目标对象和代理对象都要进行维护。
案例:
真实类:
public class real implements hometalk{
@Override
public void talk() {
System.out.println("我的房子特别好");
}
@Override
public void dosomething() {
System.out.println("来看看我的房子");
}
}
代理类:
public interface hometalk {
public void talk();
public void dosomething();
}
访问类:
public class lookhome {
public static void main(String[] args) {
System.out.println("客户:");
System.out.println("来看房子");
hometalk ht = new real();
ht.talk();
ht.dosomething();
}
}
动态代理
- 动态代理技术就是动态的创建类的技术,利用JDK的api动态的在内存中构建了对象。这样代理接口就不需要动实现接口了。态代理技术又分为两种一种是JDK动态代理另外一种是cglib动态代理。
- JDK动态代理:
- 基于接口技术(java.long.reflect.Proxy)实现接口,重写接口中的方法。这种方式目标对象一定要实现接口否则需不能使用这种方式。要使用newProxyInstance()方法。该方法需要传入三个参数。
- Java.lang.reflect.Proxy类可以直接生成一个代理对
- Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
- Object proxy:代理对象本身的引用。一般用不着。
- Method method:当前调用的方法。
- Object[] args:当前方法用到的参数
- ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。
- Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。
- InvocationHandler:策略(方案)设计模式的应用。如何代理?
InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行
- Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
public class lookhome {
public static void main(String[] args) {
System.out.println("客户:");
System.out.println("来看房子");
hometalk ht = new real();
// Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
// ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。
// Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。
// InvocationHandler:策略(方案)设计模式的应用。如何代理?
hometalk proxy = (hometalk) Proxy.newProxyInstance(ht.getClass().getClassLoader(), ht.getClass().getInterfaces(), new InvocationHandler() {
// InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行
// Object proxy:代理对象本身的引用。一般用不着。
// Method method:当前调用的方法。
// Object[] args:当前方法用到的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("中介:");
Object o = method.invoke(ht, args);
return o;
}
});
proxy.talk();
proxy.dosomething();
}
}
总结
一开始我还不是很懂有点懵懵的,但是看了下面的链接里面的我突然清晰很多,很推荐:https://blog.csdn.net/hangdongyao/article/details/79552674?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158564562719724848364309%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158564562719724848364309&biz_id=0&utm_source=distribute.pc_search_result.none-task