关于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流程图: