一、静态代理
抽象主题角色:
package com.roger.test.proxy;
public interface Subject {
void request(String name);
}
真实主题角色:
package com.roger.test.proxy;
public class SubjectImpl implements Subject {
@Override
public void request(String name) {
System.out.println("Hello " + name);
}
}
代理角色:
package com.roger.test.proxy;
public class Proxy implements Subject {
private Subject subject;
public Proxy() {
subject = new SubjectImpl();
}
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
@Override
public void request(String name) {
before();
subject.request(name);
after();
}
}
客户端:
package com.roger.test.proxy;
public class Client {
public static void main(String[] args) {
Subject subject = new Proxy();
subject.request("Roger");
}
}
缺点:每一套主题角色都需要配套一个代理角色。
二、JDK动态代理
抽象主题角色和真实主题角色与静态代理一致,但代理角色与主题角色不相关,代理角色实现的是java.lang.reflect.InvocationHandler:
package com.roger.test.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Proxy implements InvocationHandler {
private Object target;
public Proxy(Object target) {
this.target = target;
}
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
@SuppressWarnings("unchecked")
public T getProxy() {
return (T) java.lang.reflect.Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
}
客户端:
package com.roger.test.proxy;
public class Client {
public static void main(String[] args) {
Subject subject = new Proxy(new SubjectImpl()).getProxy();
subject.request("Roger");
}
}
缺点:主题需要区分抽象主题和真实主题,即接口和类,无法直接代理类。
三、CGLib动态代理
在JDK动态代理基础上更进一步,CGLib动态代理中只有两个角色,即代理角色和主题角色,代理角色实现了CGLib的MethodInterceptor接口,该接口在Spring和Hibernate中都有实现。
主题角色:
package com.roger.test.proxy;
public class SubjectB {
public void request(String name) {
System.out.println("Hello " + name);
}
}
代理角色:
package com.roger.test.proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibProxy implements MethodInterceptor {
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
@SuppressWarnings("unchecked")
public T getProxy(Class cls) {
return (T) Enhancer.create(cls, this);
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(obj, args);
after();
return result;
}
}
客户端:
package com.roger.test.proxy;
public class Client {
public static void main(String[] args) {
new CGLibProxy().getProxy(SubjectB.class).request("Roger");
}
}