代理模式。静态代理,动态代理,CGLib代理
参考:https://www.cnblogs.com/puyangsky/p/6218925.html
代理模式

3个组成部分:1、接口 2、接口实现类 3、代理类
静态代理
接口类
interface Person {
void speak();
}
接口实现类:
class Actor implements Person {
private String content;
public Actor(String content) {
this.content = content;
}
@Override
public void speak() {
System.out.println(this.content);
}
}
代理类:
class Agent implements Person {
private Actor actor;
private String before;
private String after;
public Agent(Actor actor, String before, String after) {
this.actor = actor;
this.before = before;
this.after = after;
}
@Override
public void speak() {
//before speak
System.out.println("Before actor speak, Agent say: " + before);
//real speak
this.actor.speak();
//after speak
System.out.println("After actor speak, Agent say: " + after);
}
}
测试类:
public class StaticProxy {
public static void main(String[] args) {
Actor actor = new Actor("I am a famous actor!");
Agent agent = new Agent(actor, "Hello I am an agent.", "That's all!");
agent.speak();
}
}
结果:

静态代理的核心思想:代理类中包含接口实现类,在代理类中调用接口。
动态代理
首先介绍一下最核心的一个接口和一个方法:
首先是java.lang.reflect包里的InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
我们对于被代理的类的操作都会由该接口中的invoke方法实现,其中的参数的含义分别是:
- proxy:被代理的类的实例
- method:调用被代理的类的方法
- args:该方法需要的参数
代理类实现InvocationHandler接口,通过 invoke方法调用实际的接口实现类方法
另外一个很重要的静态方法是java.lang.reflect包中的Proxy类的newProxyInstance方法:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
其中的参数含义如下:
- loader:被代理的类的类加载器 。interfaceClazz.getClassLoader(),即接口类的类加载器
- interfaces:被代理类的接口数组。new Class[]{interfaceClazz},即接口类
- invocationHandler:就是刚刚介绍的调用处理器类的对象实例。就是代理类实例
接口:
public interface Fruit {
public void show();
}
接口实现类:
public class Apple implements Fruit{
@Override
public void show() {
System.out.println("<<<<show method is invoked");
}
}
代理类
public class DynamicAgent {
//实现InvocationHandler接口,并且可以初始化被代理类的对象
static class MyHandler implements InvocationHandler {
private Object proxy;
public MyHandler(Object proxy) {
this.proxy = proxy;
}
//自定义invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(">>>>before invoking");
//真正调用方法的地方
Object ret = method.invoke(this.proxy, args);
System.out.println(">>>>after invoking");
return ret;
}
}
//返回一个被修改过的对象
public static Object agent(Class interfaceClazz, Object proxy) {
return Proxy.newProxyInstance(interfaceClazz.getClassLoader(), new Class[]{interfaceClazz},
new MyHandler(proxy));
}
}
测试:
public class ReflectTest {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
//注意一定要返回接口,不能返回实现类否则会报错
Fruit fruit = (Fruit) DynamicAgent.agent(Fruit.class, new Apple());
fruit.show();
}
}
结果:

缺点:必须实现接口
CGLIB库的方法 核心:动态生成一个被代理类的子类,子类重写被代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。
CGlib是一个字节码增强库,为AOP等提供了底层支持
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGlibAgent implements MethodInterceptor {
private Object proxy;
public Object getInstance(Object proxy) {
this.proxy = proxy;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.proxy.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
//回调方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(">>>>before invoking");
//真正调用
Object ret = methodProxy.invokeSuper(o, objects);
System.out.println(">>>>after invoking");
return ret;
}
public static void main(String[] args) {
CGlibAgent cGlibAgent = new CGlibAgent();
Apple apple = (Apple) cGlibAgent.getInstance(new Apple());
apple.show();
}
}

参考:https://www.jianshu.com/p/829e93528d56
被代理类:
public class HelloServiceImpl {
public void sayHello(){
System.out.println("Hello Zhanghao");
}
public void sayBey(){
System.out.println("Bye Zhanghao");
}
}
代理类,实现
public class HelloMethodInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before: " + method.getName());
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("After: " + method.getName());
return object;
}
}
测试:
public class Client {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/zhanghao/Documents/toy/spring-framework-source-study/");
Enhancer enhancer = new Enhancer();
//继承被代理类
enhancer.setSuperclass(HelloServiceImpl.class);
//设置回调
enhancer.setCallback(new HelloMethodInterceptor());
//设置代理类对象
HelloServiceImpl helloService = (HelloServiceImpl) enhancer.create();
//在调用代理类中方法时会被我们实现的方法拦截器进行拦截
helloService.sayBey();
}
}
result:
Before: sayBey
Bye Zhanghao
After: sayBey
核心思想:代理类实现MethodInterceptor结果。通过Enhancer将被代理类设置成超类,代理类设置为回调,通过create()创建实例,通过实例调用方法,即完成调用
浙公网安备 33010602011771号