静态代理:
/*
* 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
*在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以
* 在客户端和目标对象之间起到中介的作用
* 代理模式一般涉及到的角色有
*抽象角色:声明真实对象和代理对象的共同接口
*代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,
*同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。
*同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
*真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
*/
interface Subject
{
void invoke();
}
class RealSubject implements Subject
{
@Override
public void invoke() {
System.out.println("from realsubject");
}
}
class ProxySubject implements Subject
{
private RealSubject real;
@Override
public void invoke()
{
this.preInvoke();
if(null==real)
{
real = new RealSubject();
}
real.invoke();
this.postInvoke();
}
private void preInvoke()
{
System.out.println("pre Invoke");
}
private void postInvoke()
{
System.out.println("post Invoke");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
ProxySubject subject = new ProxySubject();
subject.invoke();
}
}
动态代理:
/*
* Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
*(1)Interface InvocationHandler:该接口中仅定义了一个方法
*public object invoke(Object obj,Method method, Object[] args)
*在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,
*args为该方法的参数数组。这个抽象方法在代理类中动态实现。
*(2)Proxy:该类即为动态代理类,其中主要包含以下内容
*protected Proxy(InvocationHandler h):构造函数,用于给内部的h赋值。
*static Class getProxyClass (ClassLoader loader, Class[] interfaces):
*获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
*static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):
*返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)
*所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,
*在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。
*你当然可以把该class的实例当作这些interface中的任何一个来用。当然,
*这个Dynamic Proxy其实就是一个Proxy,
*它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作
*在使用动态代理类时,我们必须实现InvocationHandler接口
* */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyTest {
public static void main(String[] args) {
RealSubject2 real = new RealSubject2();
InvocationHandler hander = new DynamicSubject(real);
Class<?> classType = hander.getClass();
Subject2 sub = (Subject2)Proxy.newProxyInstance(classType.getClassLoader(), real.getClass().getInterfaces(), hander);
sub.request();
}
}
interface Subject2
{
public void request();
}
class RealSubject2 implements Subject2
{
@Override
public void request() {
System.out.println("from real subject");
}
}
class DynamicSubject implements InvocationHandler
{
private Object sub;
public DynamicSubject(Object obj)
{
this.sub = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
method.invoke(sub, args);
return null;
}
}