在 findEligibleAdvisors
中会有三个步骤:
- 找到所有的 Advisor
- 筛选符合条件的 Advisor
- 对结果进行排序
我们先来看看 findCandidateAdvisors
是如何查找所有的 Advisor
protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } // 核心是调用 // BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans public List<Advisor> findAdvisorBeans() { // Determine list of advisor bean names, if not cached already. // 获取所有的 advisorNames String[] advisorNames = this.cachedAdvisorBeanNames; if (advisorNames == null) { // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the auto-proxy creator apply to them! // advisor 的所有 bean 查找 advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } if (advisorNames.length == 0) { return new ArrayList<>(); } // 获取所有的 advisors 实例 List<Advisor> advisors = new ArrayList<>(); for (String name : advisorNames) { if (isEligibleBean(name)) { if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isTraceEnabled()) { logger.trace("Skipping currently created advisor '" + name + "'"); } } else { try { advisors.add(this.beanFactory.getBean(name, Advisor.class)); } catch (BeanCreationException ex) { Throwable rootCause = ex.getMostSpecificCause(); if (rootCause instanceof BeanCurrentlyInCreationException) { BeanCreationException bce = (BeanCreationException) rootCause; String bceBeanName = bce.getBeanName(); if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) { if (logger.isTraceEnabled()) { logger.trace("Skipping advisor '" + name + "' with dependency on currently created bean: " + ex.getMessage()); } // Ignore: indicates a reference back to the bean we're trying to advise. // We want to find advisors other than the currently created bean itself. continue; } } throw ex; } } } } return advisors; }
然后接下来就是对 Advice 进行筛选
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } // 核心是调用 AopUtils.findAdvisorsThatCanApply 方法 public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
最后在对这些 Advisor 进行排序
生成代理对象
获取到当前 bean 符合条件的 Advice 过后,Spring 就会进行 Bean 代理对象的创建
Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
核心就是 createProxy
方法
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable 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()) { // Explicit handling of JDK proxy targets (for introduction advice scenarios) if (Proxy.isProxyClass(beanClass)) { // Must allow for introductions; can't just set interfaces to the proxy's interfaces only. for (Class<?> ifc : beanClass.getInterfaces()) { proxyFactory.addInterface(ifc); } } } else { // No proxyTargetClass flag enforced, let's apply our default checks... if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 构造 advisor, 在里面会进行二次匹配 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); // 添加通知 proxyFactory.addAdvisors(advisors); // 被代理对象 proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // Use original ClassLoader if bean class not locally loaded in overriding class loader ClassLoader classLoader = getProxyClassLoader(); if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) { classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader(); } // 获取代理对象 return proxyFactory.getProxy(classLoader); }
选择动态代理
Spring 在进行动态代理的时候会进行选择 GCLIB 或者 JDK 动态代理, 具体在 DefaultAopProxyFactory
中实现的逻辑。简单的理解为如果 bean 实现了接口就采用 JDK 代理, 如果没有实现就采用 GCLIB 代理,但是会有一些的参数可以特殊控制如: proxyTargetClass,optimize 等 。代码如下:
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!NativeDetector.inNativeImage() && (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."); } // 如果实现接口,采用 JDK 代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } // 否者采用 Cglib 代理 return new ObjenesisCglibAopProxy(config); } else { // 采用 JDK 代理 return new JdkDynamicAopProxy(config); } } /** * Determine whether the supplied {@link AdvisedSupport} has only the * {@link org.springframework.aop.SpringProxy} interface specified * (or no proxy interfaces specified at all). */ private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } }
最后通过动态的方式完成代理对象的创建。
参考文档
- [spring.io](● spring.io)