生活场景
想象你现在正准备租房子。你有两个选择,第一个是直接找房东租房,一个房东只有一套房子出租,你每找到一个房东只能看一套房子;第二个你可以找到中介。中介是房东的代理人,并且一个中介手里面往往有多套房子,这是不是扩展了房东只有一套房的功能?
代理模式为一个对象提供一个替身,以提供对这个对象的访问。即通过代理对象访问目标对象,这样做的好处是:可以在目标对象的实现基础上,为其增加额外的功能,即扩展目标对象的功能。
代理模式主要分为两种,一种是静态代理,一种是动态代理。
主要角色
- 被代理角色
- 代理角色
静态代理
优点:在不修改目标对象的前提下,能通过代理对象对目标对象进行扩展。 缺点:因为代理对象和目标对象都需要实现一样的接口,所以会有很多的代理类,一旦接口增加方法的话,目标对象和代理对象都要维护。
动态代理
- JDK动态代理 === 要求被代理的类必须要实现一个接口
public class TeacherDaoProxy {
private Object target;
public TeacherDaoProxy(Object target){
this.target = target;
}
public Object getProxyInstance(){
Object o = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK动态代理开始.......");
Object obj = method.invoke(target, args);
return obj;
}
});
return o;
}
}
最重要的就是两个类:Proxy和InvocationHandler。
Proxy用来返回一个代理对象,InvocationHandler用来实现对被代理对象的增强。
Cglib代理 ====== 不要求被代理类实现一个接口
public class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancreaer.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Cglib动态代理开始~~ʼ");
Object returnVal = method.invoke(target, args);
System.out.println("Cglib动态代理结束~~");
return returnVal;
}
}
重点是两个:Enhancer 和 实现MethodInterceptor并重写intercept方法。
Enhancer类用来返回一个代理对象,intercept方法中用来实现对代理对象方法的增强。