1.导入log4j.jar,开启log4j DEBUG模式
2.查看打印日志,可以发现一个重要信息:
2020-03-03 15:13:31,870 DEBUG [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator] - Creating implicit proxy for bean 'userService' with 0 common interceptors and 4 specific interceptors
spring再执行aop时,执行了 AnnotationAwareAspectJAutoProxyCreator 类中的某个方法
3.通过 AnnotationAwareAspectJAutoProxyCreator 找到最终执行的是其父类 AbstractAutoProxyCreator 中的 protected Advisor[]
buildAdvisors(String beanName, Object[] specificInterceptors) 方法
4. 重新在 buildAdvisors 这个方法打断点进行调试
5.AbstractAutoProxyCreator 类中发现有一个重要的方法createProxy 如下:
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 核心代码 return proxyFactory.getProxy(getProxyClassLoader()); }
接着进入 ProxyFactory 中的 getProxy 方法
public Object getProxy(ClassLoader classLoader) { // createAopProxy 方法中判断是选择jdk动态代理还是cglib方式代理 return createAopProxy().getProxy(classLoader); }
再进入到 ProxyCreatorSupport 中的 createAopProxy 方法
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // getAopProxyFactory() 返回的是 DefaultAopProxyFactory对象,所以重点还是在 createAopProxy 方法上 return getAopProxyFactory().createAopProxy(this); }
6.进入到 DefaultAopProxyFactory 类中的 createAopProxy 方法,这个方法就是如何选择JDK动态代理还是Cglib代理
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // 1.config.isProxyTargetClass() 代表 配置中的proxy-target-class属性true/false,默认false // if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { // 目标代理类,如 com.service.impl.UserServiceImpl 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); } }
方法中参数config 是一个 AdvisedSupport类型, AdvisedSupport 继承了 ProxyConfig 类,
public class ProxyConfig implements Serializable { // 代表 配置中的proxy-target-class,如果设置true,则使用Cglib方式代理 private boolean proxyTargetClass = false; private boolean optimize = false; boolean opaque = false; boolean exposeProxy = false; private boolean frozen = false; // 省略部分代码 }