代理模式:
为其他对象提供一种代理以控制对这个对象的访问,有时委托类不适合或不能直接引用另一个对象时,代理类就在两方之间起到一个桥梁的作用。代理设计模式符合开闭原则 ,在不修改原有类的基础上,增强原有类的功能逻辑。
代理模式优点:
增强真实对象
保护真是对象
降低系统耦合度,扩展性好
代理模式缺点:
代理类使系统设计时的类增多
静态代理: 一个接口,两个类:真实业务类,代理类
静态体现在:代理类和真实类的关系在程序运行前就确定了
在静态代理的实现中,需要定义一个接口,真实业务类和代理类都要实现这个接口,同时在代理类中,要定义一个真实对象的引用,通过构造方法传给代理类对象,然后在调用业务方法时,调用真实类的业务实现
//定义了业务的实现规范
interface Buy {
void buyMac();
void buyGivenchy();
}
//真实类(委托类)真实业务的实现
class Real implements Buy{
@Override
public void buyMac() {
System.out.println("buy a mac");
}
@Override
public void buyGivenchy() {
System.out.println("buy a givenchy");
}
}
//代理类 代理Real类搜集有的功能,并做额外的增强
class ProxyClass implements Buy{
//引用接口对象使得代理类可以访问实体
private Buy buy;
public ProxyClass(Buy buy){
this.buy = buy;
}
//其实代理类的本质还是用了委托类的具体方法
@Override
public void buyMac() {
System.out.println("买");
this.buy.buyMac();
}
@Override
public void buyGivenchy() {
System.out.println("买");
this.buy.buyGivenchy();
}
}
public class ProxyDemo {
public static void main(String[] args) {
Buy buy = new ProxyClass(new Real());
buy.buyMac();
buy.buyGivenchy();
}
}
静态代理是效率最高效率的代理模式,但它也存在缺陷
**静态代理缺陷:**每一个需要被代理的类或接口,都要为其实现一个代理类,如果需要代理的类或接口很多,就导致要实现的代理类也很多,这时引入动态代理。动态代理是由一个代理类来代理所有需要被代理的类或接口
动态代理:
在程序运行时有JVM创建代理类,此时的这个代理类可以代理任何需要被代理的类或接口,动态体现在这里
今天来说JDK代理:
JDK代理就是使用JDK内置的方法去实现代理模式,有两个核心的类Proxy和InvocationHandle
Proxy:调度器
InvocationHandle:增强器
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
有三个参数:
真是对象的类加载器
真是对象实现的接口
真实对象实例
实现动态代理:
interface ISubject{
public void eat(int num,String msg);
}
//真是业务类
class RealImpl implements ISubject{
@Override
public void eat(int num,String msg) {
System.out.println("I want to buy "+ num + msg);
}
}
//实现InvocationHandler的代理类
class ProxySubject implements InvocationHandler{
private Object target;
public ProxySubject(){ }
public Object bind(Object target){
this.target = target;
//通过JDK获取代理类对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);//此时的this是真实类的对象
}
public void preHandle(){
System.out.println("before buy");
}
public void afterHandle() {
System.out.println("after buy");
}
//通过invoke方法对真是业务做增强以及调用真实业务
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.preHandle();
Object obj = method.invoke(this.target,args);
this.afterHandle();
return obj;
}
}
public class JDKProxyDemo {
public static void main(String[] args) {
ISubject subject = (ISubject) new ProxySubject().bind(new RealImpl());
//此时真实类与代理已经建立联系
subject.eat(3,"apples");
}
}