Spring Boot源码(八):Spring AOP源码
关于spring aop的应用参见:Spring AOP-基于@AspectJ风格
spring在初始化容器时就会生成代理对象:
关于创建bean的源码参见:Spring Boot源码(六):Bean的创建详解
我们进入createBean()的doCreateBean()方法:
其中的initializeBean():
其中的applyBeanPostProcessorsBeforeInitialization():
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
此方法是拿到各种各样的后置处理器,去处理对象。
再次加上条件断点:
第5个是我们处理aop的后置处理器。如果我们没有使用aop,那就没有它。
进入此类AbstractAutoProxyCreator的方法:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
wrapIfNecessary()方法:
进入createProxy()方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { 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."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
如果该类实现接口,用jdk代理,否则使用cglib代理,默认是jdk代理。
再来看getProxy():
它有两个实现类:
JdkDynamicAopProxy#getProxy()
public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
最后一行就是jdk代理的代码了。可见JDK动态代理。
附debug流程图: