文章目录
前言
提示:代理模式一般通过实现接口或者继承父类来实现对目标对象的访问
一、代理模式是什么?
访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
目的: 一是保护目标对象(间接访问对象);
二是增强目标对象(可以前置,后置或者环绕增强,处理异常等,如SpringAOP)。
二、代理模式简介
1.接口代理(如JDK动态代理)
静态代理:
目标对象 A 实现接口 B重写方法 request();
代理类 Proxy 也同样实现 接口 B, 并且通过聚合方式将目标作为代理Proxy的成员
代理Proxy 重写方法 request(),拦截了目标A的方法request(),能够对其前置,后置等增强处理
缺点:必须有接口,jdk动态代理还使用了反射,效率没有cglib快
2.继承代理(如cglib动态代理的实现,Spring AOP)
继承代理方式 通过对真实目标进行继承重写请求方法来处理
缺点: 被代理类不能是final修饰的
原理大概如下:
aop:
cglib动态代理 SpringAOP(源码分析):
MethodInterceptor: 方法拦截接口
public interface MethodInterceptor extends Callback {
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}
CglibAopProxy.class
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
//真实被代理对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
//被代理对象作为父类,代理者是他的子类
Class<?> proxySuperClass = rootClass;
int x;
if (rootClass.getName().contains("$$")) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
Class[] var5 = additionalInterfaces;
int var6 = additionalInterfaces.length;
for(x = 0; x < var6; ++x) {
Class<?> additionalInterface = var5[x];
this.advised.addInterface(additionalInterface);
}
}
this.validateClassIfNecessary(proxySuperClass, classLoader);
//Enhancer 动态代理 拦截方法的处理类
Enhancer enhancer = this.createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//给代理设置父类
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = this.getCallbacks(rootClass);
Class<?>[] types = new Class[callbacks.length];
for(x = 0; x < types.length; ++x) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
//返回代理子类
return this.createProxyClassAndInstance(enhancer, callbacks);
} catch (IllegalArgumentException | CodeGenerationException var9) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", var9);
} catch (Throwable var10) {
throw new AopConfigException("Unexpected AOP exception", var10);
}
}
总结
接口代理必须要有接口,而继承方式则不能是final.
写文不易,有错误的地方还望评论区指正补充! 谢谢