Spring AOP源码浅析(上篇)

勿忘初心2018-09-04 11:15
作者:梁宏达
四、AOP生成代理
    第二步已经把所有的标签生成了RootBeanDefinition,configureAutoProxyCreator(parserContext, element)这个方法生成了AOP核心类AspectJAwareAdvisorAutoProxyCreator,该类的类关系图:

    AspectJAwareAdvisorAutoProxyCreator是BeanPostProcessor的实现类,核心就在postProcessAfterInitialization(....)这里,该方法会生成代理类。
    Spring的启动过程在AbstractApplicationContext的refresh()进行。
        @Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// 创建BeanFactory,没有就创建,第二步就在这里发生的(BeanDefinition的装载)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// 子类可以获取BeanFactoreanFactory
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册所有实现实现了BeanPostProcessor的类,存储在DefaultListableBeanFactory,beanFactory持有上述加载的所有的Bean,其中AspectJAwareAdvisorAutoProxyCreator也在其中 
                                // 其中BeanId是org.springframework.aop.config.internalAutoProxyCreator,获取不到就create
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// 最关键的Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

最关键的是finishBeanFactoryInitialization(beanFactory),实例化所有非懒加载的Bean(回顾Bean的生命周期):

  1. 通过构造函数实例化
  2. 设置属性
  3. 回调BeanNameAware、BeanFactoryAware等接口子类的方法
  4. 遍历BeanPostProcessor的子类,然后回调他们的实现的两个方法(所谓BeanProcessor回调)
  5. 回调InitializingBean
  6. ini-method属性....后续都是Bean的生命周期中的内容,关键要看第4步
当前Spring中有6个Bean和4个BeanPostProcessor:


举例说明,当根据Spring Bean生命周期,math在实例化(create)之前,调用BeanPostProcessor的子类的before方法,下面是代码片段:

上面的红框是用于调用BeanPostProcessor的前置方法,AOP的代理类在BeanPostProcessor的后置方法中生成。
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
                       // 调用后置处理器
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}
    接下来调用AbstractAutoProxyCreator的postProcessAfterInitialization(....):
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
    我们跟wrapIfNecessary(bean, beanName, cacheKey),该方法只对math做了进一步的处理:
          protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
                // this.advisedBeans这个map中包含beanI->boolean,不可以进一步则进入到下一步判断
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 当前beanName如果有advice则可以为其创建代理,这里先去查找符合条件的advice
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
    查找代理,接下来对当前beanName的符合条件的Advice进行查找:
	@Override
	protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
                // 查找Advice
		List advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

	protected List findEligibleAdvisors(Class beanClass, String beanName) {
                // 所有的潜在Advice
		List candidateAdvisors = findCandidateAdvisors();
		// 选取符合条件的Advice
                List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);    // 在链表头添加一个默认ExposeInvocationInterceptor
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
        /** 获取pc的正则表达式,然后获取target的方法列表和正则表达式对比,满足返回true **/
      public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}  
                // Pointcut的正则表达式
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {    // 类型转换
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set> classes = new LinkedHashSet>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class clazz : classes) {
			Method[] methods = clazz.getMethods();    // 目标对象的方法
			for (Method method : methods) {
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}
    获取了所有的Adivce后,就可以生成代理对象了:
        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);
                // proxy-target-class属性
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
                // Advice封装到ProxyFactory
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
                // 创建代理
		return proxyFactory.getProxy(getProxyClassLoader());
	}

        // 根据配置生成代理
        @Override
	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);
		}
	}

        public Object getProxy(ClassLoader classLoader) {
                // createAopProxy()获取代理,然后具体细节在getProxy()中
		return createAopProxy().getProxy(classLoader);
	}


相关阅读:Spring AOP源码浅析(上篇)

网易云大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者梁宏达授权发布