没看过代理模式之前感觉很高深,其实代理模式很好理解。
代理模式:代理模式顾名思义,就是在根本目标之前加上扩展,加上扩展之后的产物就是代理对象了,整个模式就是代理模式了。
原理图:
代理模式有三种实现方式
一、静态代理
/**
* Created by wangsheng on 2018/3/14.
*/
public interface IActor {
void act();
}
/**
* Created by wangsheng on 2018/3/14.
*/
public class ImpActor implements IActor {
private static final String TAG = "ImpActor";
@Override
public void act() {
Log.d(TAG, "act: 我只是个演员");
}
}
/**
* Created by wangsheng on 2018/3/14.
*/
public class ActorProxy implements IActor {
private static final String TAG = "ActorProxy";
ImpActor impActor;
public ActorProxy(ImpActor impActor) {
this.impActor=impActor;
}
@Override
public void act() {
Log.d(TAG, "act: 我是代理,想让演员表演先经过我的同意!");
impActor.act();
}
}
client:
//代理模式
ImpActor impActor=new ImpActor();
ActorProxy actorProxy=new ActorProxy(impActor);
actorProxy.act();
输出:
可以看出演员和代理或者称之为经纪人都实现了相同的接口,对目标对象进行扩展的时候不需要修改目标对象。
但是静态代理的缺点也很明显当需要对不同目标对象进行代理的时候需要很多代理类,而且一旦接口变化就需要对目标对象还有代理对象同时进行维护,很不方便。
二、动态代理
动态代理很好的解决了静态代理的问题,动态代理模式下,代理对象不需要实现目标对象实现的接口,它是利用jdk中的api动态在内存中生成代理对象。
/**
* Created by PC on 2018/3/15.
*/
public interface IActor {
void act();
}
/**
* Created by PC on 2018/3/15.
*/
public class ImpActor implements IActor {
private static final String TAG = "ImpActor";
@Override
public void act() {
Log.d(TAG, "act: 我只是个演员");
}
}
/**
* Created by PC on 2018/3/15.
*/
public class ProxyFactory {
private static final String TAG = "ProxyFactory";
ImpActor impActor;
public ProxyFactory(ImpActor impActor) {
this.impActor=impActor;
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(impActor.getClass().getClassLoader(), impActor.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log.d(TAG, "invoke: 代理拦截");
Object returnvalue=method.invoke(impActor,args);
return returnvalue;
}
});
}
}
client:
ImpActor impActor=new ImpActor();
ProxyFactory proxyFactory=new ProxyFactory(impActor);
IActor proxy= (IActor) proxyFactory.getProxyInstance();
proxy.act();
输出:
动态代理虽然解决了静态代理的缺点,但是这种模式仍然需要目标对象实现接口,如果目标对象没有接口,则需要Cglib代理模式
三、Cglib代理
Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展。
特点:目标对象没有实现任何接口,用动态生成子类的的方式实现对目标对象的功能扩展。
/**
* Created by PC on 2018/3/15.
*/
public class ImpActor {
private static final String TAG = "ImpActor";
public void act() {
Log.d(TAG, "act: 我只是个演员");
}
}
public class ProxyCGlib implements MethodInterceptor {
private static final String TAG = "ProxyCGlib";
ImpActor impActor;
public ProxyCGlib(ImpActor impActor) {
this.impActor=impActor;
}
public Object getProxyInstance(){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(ImpActor.class);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Log.d(TAG, "intercept: CGlib代理拦截了一下");
Object object=method.invoke(impActor,objects);
return object;
}
}
client:
ImpActor impActor=new ImpActor();
ProxyCGlib proxyCGlib=new ProxyCGlib(impActor);
ImpActor impActor1= (ImpActor) proxyCGlib.getProxyInstance();
impActor1.act();
需要导入spring-core的jar包,用到的Enhancer和MethodInterceptor接口依赖这个包。欢迎评论,你的点赞和意见是我进步的最大动力。