书接上文,上文说到,specificInterceptors 不为空则执行createProxy方法创建代理对象,即下图的createProxy方法开始执行,生成代理对象,生成代理对象有两种方式,JDK和CGLIB。
createAopProxy就是决定使用哪种方式生成动态代理对象,方法执行流程和代码如下:
/**
* 真正的创建代理,判断一些列条件,有自定义的接口的就会创建jdk代理,否则就是cglib
* @param config the AOP configuration in the form of an
* AdvisedSupport object
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 这段代码用来判断选择哪种创建代理对象的方式
// config.isOptimize() 是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
// config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
// hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是SpringProxy类型
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 上面的三个方法有一个为true的话,则进入到这里
// 从AdvisedSupport中获取目标类 类对象
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.");
}
// 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
// 如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 配置了使用Cglib进行动态代理或者目标类没有接口,那么使用Cglib的方式创建代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用JDK的提供的代理方式生成代理对象
return new JdkDynamicAopProxy(config);
}
}
此处使用ObjenesisCglibAopProxy方式
getProxy:168, CglibAopProxy (org.springframework.aop.framework)
创建代理对象方法及注释如下:
/**
* 获取cglib的代理对象
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return
*/
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 从advised中获取ioc容器中配置的target对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
//如果目标对象已经是CGLIB 生成代理对象(就是比较类名称中有 $$ 字符串),那么就取目标对象的父类作为目标对象的类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
// 获取原始父类的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 打印出不能代理的方法名,CGLIB 是使用继承实现的,所以final , static 的方法不能被增强
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 创建及配置Enhancer
Enhancer enhancer = 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));
// 获取callbacks
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 通过 Enhancer 生成代理对象,并设置回调
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
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",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
rootClass是需要被代理的对象,Enhancer该类用于生成代理对象,代理如何生成:CGLIB和JDK两种生成方式。
getProxy:168, CglibAopProxy (org.springframework.aop.framework)
getProxy:116, ProxyFactory (org.springframework.aop.framework)
createProxy:519, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:383, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:319, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:529, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:2273, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:736, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:630, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:417, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 71399214 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:370, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:414, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:260, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:993, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:1024, AbstractApplicationContext (org.springframework.context.support)
refresh:614, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:87, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TestAop (com.mashibing.aop.xml)
一级缓存里是MyCalculator的代理对象 后续执行就是这个代理对象的方法,然后跳转到
intercept:709, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
这个方法
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 从advised中获取配置好的AOP通知
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
// 如果没有aop通知配置,那么直接调用target对象的调用方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果拦截器链为空则直接激活原方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 通过cglibMethodInvocation来启动advice通知
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other ||
(other instanceof DynamicAdvisedInterceptor &&
this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
}
chain = {ArrayList@2276} size = 6
0 = {ExposeInvocationInterceptor@2242}
1 = {AspectJAfterThrowingAdvice@2282} “org.springframework.aop.aspectj.AspectJAfterThrowingAdvice: advice method [public static void com.mashibing.aop.xml.util.LogUtil.logException(org.aspectj.lang.JoinPoint,java.lang.Exception)]; aspect name ‘logUtil’”
2 = {AfterReturningAdviceInterceptor@2283}
3 = {AspectJAfterAdvice@2284} “org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public static void com.mashibing.aop.xml.util.LogUtil.logFinally(org.aspectj.lang.JoinPoint)]; aspect name ‘logUtil’”
4 = {AspectJAroundAdvice@2285} “org.springframework.aop.aspectj.AspectJAroundAdvice: advice method [public java.lang.Object com.mashibing.aop.xml.util.LogUtil.around(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable]; aspect name ‘logUtil’”
5 = {MethodBeforeAdviceInterceptor@2286}
执行的就是上面6个的通知,通过索引下标挨个执行
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
执行顺序如下:
本文主要讲解springAop如何创建动态代理对象以及使用哪种方式创建的依据;在执行方法跳转到生成的代理对象中,然后生成拦截器链去执行