目录
1. 代理模式
2. 静态代理
3. 动态代理
3.1 JDK 动态代理
3.2 CGLIB 动态代理
4. JDK 动态代理和 CGLIB 动态代理对比
5. Spring代理选择
6. Spring AOP 实现原理
6.1 织入
7. JDK 动态代理实现
8. CGLIB 动态代理实现
9. 总结
代理模式分为静态代理和动态代理。
静态代理实现步骤:
这样,我们就可以通过代理类屏蔽目标对象的访问,并且可以在目标方法执行前后实现其他的功能。接下来,我们来看一下具体是如何实现静态代理的:
1. 定义接口
2. 实现接口
3. 创建代理类并同样实现支付接口
4. 实际使用
相比于静态代理来说,动态代理更加灵活。我们不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口,我们可以直接代理实现类( CGLIB 动态代理机制)。
定义 JDK 动态代理类:
创建一个代理对象并使用:
因此,可以通过 CGLIB 动态代理机制来避免。
CGLIB 动态代理类使用步骤:
添加依赖:
和JDK 动态代理不同, CGLIB(Code Generation Library) 实际是属于⼀个开源项目,使用时需要手动添加相关依赖。
cglib
cglib
3.3.0
自定义 MethodInterceptor(方法拦截器):
创建代理类, 并使用:
public interface PayService {
void pay();
}
public class AliPayService implements PayService{
@Override
public void pay(){
System.out.println("ali pay...");
}
}
public class PayServiceJDKInvocationHandler implements InvocationHandler {
// 目标对象就是被代理对象
private Object target;
public PayServiceJDKInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("安全检查");
System.out.println("记录日志");
System.out.println("记录开始时间");
// 通过反射调用被代理的方法
Object retVal = method.invoke(target,args);
System.out.println("记录结束时间");
return retVal;
}
public static void main(String[] args) {
PayService target = new AliPayService();
// 方法调用处理器
InvocationHandler handler = new PayServiceJDKInvocationHandler(target);
// 创建一个代理类:通过被代理类、被代理实现的接口、方法调用处理器来创建
PayService proxy =(PayService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
new Class[]{PayService.class},
handler);
proxy.pay();
}
}
public interface PayService {
void pay();
}
public class PayServiceCGLIBInterceptor implements MethodInterceptor {
// 被代理对象
private Object target;
public PayServiceCGLIBInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("安全检查");
System.out.println("记录日志");
System.out.println("记录开始时间");
// 通过反射调用被代理的方法
Object retVal = methodProxy.invoke(target,args);
System.out.println("记录结束时间");
return retVal;
}
public static void main(String[] args) {
PayService target = new AliPayService();
PayService proxy =(PayService) Enhancer.create(target.getClass(),
new PayServiceCGLIBInterceptor(target));
proxy.pay();
}
}