0.代理模式简介
已经介绍了单例模式和工厂模式,本片介绍下代理模式。
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
代理模式也挺常用的,Spring里面AOP的主要实现原理就是动态代理。
顺便提一下设计模式不是一种技术,这是一种方法,解决特定问题的方法。
1.代理模式的优点
没优点用它干啥。。。
1)保护真实对象:交给代理对象来做;
2)真实对象指责明确:不该他做的都代理对象做;
3)扩展性:不同的代理对象可以做不同事。
2.分类
1.静态代理:手动定义代理类;
2.动态代理:动态生成代理类;
1)JDK代理:JDK自带不用导jar,真实对象需要实现接口,基于反射机制,效率差点(新版的JDK对反射已经优化很多了,效率差距并不大);
2)CGLib代理:真实对象不需要实现接口,需要倒入jar。基于字节码效率略优于JDK代理。
3.静态代理
业务类只需要关注业务逻辑本身…算了直接看代码实现吧注释会说明的。
目标接口:
public interface Person {
//目标接口
void findGirl();//找对象
void appointment();//约会
}
真实对象(Tom):
public class Tom implements Person {
//委托媒婆帮自己找对象
@Override
public void findGirl() {
System.out.println("我只是Tom,我想找个Girl");
}
//真实对象
@Override
public void appointment() {
System.out.println("我是tom,我来约会了");
}
}
代理对象(媒婆):
public class RedMan implements Person {
//代理对象
private Tom tom = new Tom();
public void TomProxy(Tom tom){
this.tom = tom;
}
//帮你找对象
@Override
public void findGirl() {
System.out.println("兄弟,我帮你找对象");
}
//你得亲自去约会
@Override
public void appointment() {
tom.appointment();
}
}
调用:
public class DoIt {
public static void main(String[] args) {
RedMan redMan = new RedMan();
redMan.findGirl();
redMan.appointment();
}
}
运行结果:
兄弟,我帮你找对象
我是tom,我来约会了
结论:我们可以不对Tom类进行修改拓展他的功能,但是他找到对象要是想看电影,买车,买房…这维护起来工程可就太大了。
4.JDK动态代理
接口:
public interface Person {
public void findGirl();
}
真实对象:
public class Tom implements Person {
@Override
public void findGirl() {
System.out.println("Tom要找对象");
}
}
代理对象:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkRedMan implements InvocationHandler {
//被代理的对象
private Person target;
public Object getInstance(Tom target){
this.target=target;
Class<?> clazz=target.getClass();
//生成一个新的对象,通过字节码重组
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆,我帮你你找对象");
method.invoke(target,args);
System.out.println("Ok交给我");
return null;
}
}
测试:
package proxy.jdk;
public class JdkTest {
public static void main(String[] args) {
Person person=(Person) new JdkRedMan().getInstance(new Tom());
person.findGirl();
}}
运行结果:
我是媒婆,我帮你你找对象
Tom要找对象
Ok交给我