Springboot源码分析8——aop动态代理
springboot启动源码分析1——初步初始化
springboot启动源码分析2——run方法分析
springboot启动源码分析3——环境配置
springboot启动源码分析4——刷新容器
springboot启动源码分析5——后续处理内容
Spring Boot启动源码分析6——refresh的invokeBeanFactoryPostProcessors方法详解
springboot启动源码分析7——自动配置
springboot启动源码分析8——aop
代理类对应的调用
下面我们来讲一下springboot中的aop的动态代理是在哪里进行配置创建的。
aop的动态代理的创建getProxy主要是调用ProxyFactory中的getProxy方法进行配置相关的动态代理。
如下
该进行获取对应的aop代理的配置是在refresh()进行刷新方法的this.finishBeanFactoryInitialization(beanFactory);方法中进行对应的获取和配置的。
同样我们都知道aop的动态代理主要有cglib和JDK的动态代理,那么这里是如何进行判断的呢?
首先其在createAopProxy()的时候就会根据类型进行判断获取,进入该方法,
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
return this.getAopProxyFactory().createAopProxy(this);
}
主要看createAopProxy()方法。点进该方法。如果没有进行debug的情况下,也可以直接alt+ctrl+点击该方法直接进入,该方法就只有一个实现类DefaultAopProxyFactory。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//如果本地系统中有"org.graalvm.nativeimage.imagecode"或者是没有经过优化的,并且该配置类不能是被代理类并且没有提供代理接口,那么就直接返回JDK代理
if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
//注意这里的代理目标类不是接口,而不要当做是不是实现接口的类,并且不是代理类,并且不是Lambda类。这样就会进行cglib代理,否则就会返回JDK的动态代理。
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) && !ClassUtils.isLambdaClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
接下来我们在来看看cglib和JDK代理有什么不同
首先我们来看看cglib的动态代理
Cglib的动态代理
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 = 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));
//通过getCallbacks进行设置相对应的拦截器
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);
}
}
该动态代理是调用CglibAopProxy类中的getProxy()方法。
前面主要进行一些配置,就是获取目标类,然后在进行相对应的根据他来添加和设置一些属性。
我们主要看到最后一步,this.createProxyClassAndInstance(enhancer, callbacks)方法
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
//根据代理类进行创建实例
//这里的objenesis是当前类SpringObjenesis。
//主要就是进行判断是否使用缓存进行创建,如果使用缓存的话就直接使用instantiator来newInstance
// 否者就new一个instantiator来进行newInstance
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
} catch (Throwable var7) {
logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", var7);
}
}
if (proxyInstance == null) {
try {
Constructor<?> ctor = this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor();
ReflectionUtils.makeAccessible(ctor);
proxyInstance = this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance();
} catch (Throwable var6) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well", var6);
}
}
((Factory)proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
最后我们在烂看一下相对应的设置拦截器getCallbacks()
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
//这里是处理expose-proxy中
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
//将对应的拦截器封装到DynamicAdvisedInterceptor中
Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
Object targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
} else {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
Callback[] mainCallbacks = new Callback[]{
aopInterceptor //将拦截器加入到callback中
, (Callback)targetInterceptor
, new CglibAopProxy.SerializableNoOp()
, (Callback)targetDispatcher
, this.advisedDispatcher
, new CglibAopProxy.EqualsInterceptor(this.advised)
, new CglibAopProxy.HashCodeInterceptor(this.advised)};
Callback[] callbacks;
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
for(int x = 0; x < methods.length; ++x) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
} else {
callbacks = mainCallbacks;
}
return callbacks;
}
JDK的动态代理
下面我们再来看看对应的JDK的aop的动态代理
这里主要执行的就是JDKDynamicAopProxy继承了InvocationHandler,所以aop对应的代理会调用他的invoke方法。
如下
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
Object var12;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean var18 = this.equals(args[0]);
return var18;
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var17 = this.hashCode();
return var17;
}
if (method.getDeclaringClass() == DecoratingProxy.class) {
Class var16 = AopProxyUtils.ultimateTargetClass(this.advised);
return var16;
}
Object retVal;
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
}
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = target != null ? target.getClass() : null;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
//这里是判断是否有拦截器,如果没有什么拦截器,那么就直接调用切点的方法。
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
//对上面创建的拦截器使用ReflectiveMethodInvocation进行了链的封装。,并且在下面的proceed方法中会进行对实现的拦截器进行逐一调用
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
var12 = retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return var12;
}
我们来看一下对应的proceed()方法
@Nullable
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//这里执行完成所有的增强方法之后,在执行切点的方法。
return this.invokeJoinpoint();
} else {
//获取相对应的拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
//这里对获取的拦截器进行相对应的匹配,如果匹配成功就执行对应的拦截器方法,不匹配就不执行拦截器,而进行遍历直到是最后一步或者是有匹配的拦截器方法执行
return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
//这里是普通的拦截器,上面的是动态进行匹配的拦截器,
//如果是普通的拦截器那么就直接调用拦截器的方法。比如MethodBeforeAdviceInterceptor、AspcetJAroundAdvice等
//这里的入参为this,就是保证当前实例中调用链的执行。
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}