代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
再看看代理模式的UML图
代理模式的分类:静态代理和动态代理,其中动态代理分为JDK动态代理和CGLIB动态代理,在本文章中只讲静态代理和JDK动态代理。
在我看来静态代理和动态代理的唯一区别就是在代理这块是如何实现的,如果他在代理类中直接引用了真实对象,那他使用的就是静态代理。反之他如果是通过实现了invocationHandler的接口,并且在代理类中使用的是Objec来代表真实对象,然后通过invoke方法知道了真实对象的种类以及方法,那么他就是动态代理。换句话说也就是在代理的实现部分中,代理类并不知道将来自己要替那个真实对象去办什么事情。
下面看静态代理的代码实现:
package com.tgb;
/**
* Created by lenovo on 2017/7/24.
*/
abstract class AbstractObject{
public abstract void operation();
}
class RealObject extends AbstractObject{
@Override
public void operation() {
System.out.println("realObject的一下操作");
}
}
class ProxyObject extends AbstractObject{
//引用真实对象
private RealObject realObject=new RealObject();
public ProxyObject(RealObject realObject){
this.realObject=realObject;
}
@Override
public void operation(){
System.out.println("代理之前");
//调用真实对象的操作方法
realObject.operation();
System.out.println("代理之后");
}
}
class test{
public static void main(String[] args) {
RealObject realObject= new RealObject();
ProxyObject proxyObject=new ProxyObject(realObject);
proxyObject.operation();
}
}
再接下来看动态代理的代码实现
相信看了这两个例子之后,大家就很明白动态代理和静态代理的区别了,懂了他们,spring容器这块的内容就很容易理解了。package com.tgb; import java.lang.annotation.Target; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by oxj on 2017/7/24. */ public class 动态代理 { } interface Service{ public abstract void add(); } class UserServiceImpl implements Service{ public void add(){ System.out.println("这是添加的方法"); } } //jdk动态代理(通过实现InvocationHandler接口,重写invoke方法) class MyInvocationHandler implements InvocationHandler{ //这个Object类型的target就显示了这个是动态代理,在静态代理这部分是定义真实类型的真实对象 private Object target; MyInvocationHandler(Object target){ this.target=target; } @Override public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{ System.out.println("动态代理之前"); Object result=method.invoke(target,args); System.out.println("动态代理之后"); return result; } //通过类加载器获得当前的代理 public Object getProxy(){ ClassLoader classLoader=Thread.currentThread().getContextClassLoader(); Class<?>[] interfaces=target.getClass().getInterfaces(); //这里调用了Proxy类的静态方法newProxyInstance的方法 return Proxy.newProxyInstance(classLoader,interfaces,this); } } class ProxyTest{ public static void main(String[] args) { Service service=new UserServiceImpl(); MyInvocationHandler myInvocationHandler= new MyInvocationHandler(service); Service serviceProxy = (Service) myInvocationHandler.getProxy(); serviceProxy.add(); } }