简介:
代理模式属于结构型模式,功能是为其他对象提供一种代理以便于控制对这个对象的访问。常见实现方式有静态代理、动态代理。Spring中的AOP就是基于代理模式实现的。
具体实现及测试如下:
1. 静态代理
/**
* 定义功能接口,让代理和被代理对象进行实现
* @author dedu
*
*/
public interface ISubject {
void request();
}
/**
* 被代理者,进行实际的请求处理,并将结果返回给代理者
* @author dedu
*
*/
public class RealSubject implements ISubject {
@Override
public void request() {
System.out.println("实际请求处理者进行处理");
}
}
/**
* 静态代理:代理中保存一个被代理者的引用,当代理被调用时,内部个性化处理完后调用被代理者相应函数
* @author dedu
*
*/
public class Proxy implements ISubject {
private ISubject rs;
public Proxy(ISubject rs) {
super();
this.rs = rs;
}
@Override
public void request() {
System.out.println("代理者进行请求接收");
rs.request();
System.out.println("代理者调用实际请求结束");
}
}
测试
public static void main(String[] args) {
ISubject sub = new RealSubject();
Proxy proxy = new Proxy(sub);
proxy.request();
}
2. 动态代理
/**
* 定义功能接口,让代理和被代理对象进行实现
* @author dedu
*
*/
public interface ISubject {
void request();
}
/**
* 被代理者,进行实际的请求处理,并将结果返回给代理者
* @author dedu
*
*/
public class RealSubject implements ISubject {
@Override
public void request() {
System.out.println("实际请求处理者进行处理");
}
}
2.1 基于JDK实现
public class SubjectHandler implements InvocationHandler {
private ISubject subject;
public SubjectHandler(ISubject subject) {
super();
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理者接收请求,调用被代理者进行处理");
Object result = method.invoke(subject, args);
/* if ("checkUserPower".equals(method.getName())) { //也可以针对某个方法进行个性化处理
//其他处理
} */
System.out.println("JDK代理者接收处理结果,返回结果对象");
return result;
}
}
2.2 基于CGLib实现
/**
* 基于cglib实现动态代理,Jar包为cglib-2.2.2、asm-3.3.1
* @author dedu
*
*/
public class SubjectInterceptor implements MethodInterceptor {
private ISubject subject;
public SubjectInterceptor(ISubject subject) {
this.subject = subject;
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("CGLib代理者接收请求,调用被代理者进行处理");
Object result = arg1.invoke(this.subject, arg2);
/* if ("checkUserPower".equals(method.getName())) { //也可以针对某个方法进行个性化处理
//其他处理
} */
System.out.println("CGLib代理者接收处理结果,返回结果对象");
return result;
}
public Object createProxyInstance() {
Enhancer eh = new Enhancer();
eh.setSuperclass(this.subject.getClass());
eh.setCallback(this);
return eh.create();
}
}
测试
public static void main(String[] args) {
//JDK代理测试
ISubject realSubject = new RealSubject();
SubjectHandler handler = new SubjectHandler(realSubject);
ISubject dynamicProxy = (ISubject) Proxy.newProxyInstance(ISubject.class.getClassLoader(), new Class[] {ISubject.class}, handler);
dynamicProxy.request();
//CGLib代理测试
ISubject trueSubject = new RealSubject();
SubjectInterceptor cglibProxy = new SubjectInterceptor(trueSubject);
ISubject proxy = (ISubject) cglibProxy.createProxyInstance();
proxy.request();
}
3. 总结:
静态代理:在代理中保存一个引用使得代理可以访问实体并提供一个与实体相同的接口。
动态代理:是代理类在程序运行时创建,常见实现方式有JDK自带的动态代理类(利用反射机制生成子类)和CGLib动态代理类(利用ASM修改字节码生成子类)。
- JDK代理只能对实现了接口的类生成代理。
- CGLib可以直接对类进行代理生成,但要求类不是final,代理的方法不是final/static/private的。