Spring源码-AOP部分-Spring是如何对bean实现AOP代理的

实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1

历史文章

 

AOP代理对象也是在bean的实例化过程中创建的,如果不明白可以看一下bean实例化过程。如果类配置了@EnableAspectJAutoProxy注解 ,Spring则会在BeanPostProcessor.after这一步通过AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor创建一个代理对象,替换掉了原有的bean对象返回了出去。

 

我们再来看一下bean创建流程

Spring源码-AOP部分-Spring是如何对bean实现AOP代理的

 

创建bean方法如下

doCreateBean方法
/**
	 * 真正创建bean的方法
	 */
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// 封装被创建的bean对象
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// TODO【重要】 这一步创建了bean实例,只是一个早期的对象,还没有填充属性值
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();

		// 获取实例化对象的类型
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 调用post-processors
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 向容器中缓存单例模式的bean,防止循环引用
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// TODO【重要】 向三级缓存添加bean实例 匿名内部类,防止循环引用,尽早持有对象的引用
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 初始化bean实例,exposedObject在初始化完成之后返回依赖注入完成之后的bean
		Object exposedObject = bean;
		try {
			// TODO 【重要】 bean属性依赖注入,并且将bean定义中配置的属性值赋值给实例对象
			populateBean(beanName, mbd, instanceWrapper);

			// TODO 【重要】开始初始化bean对象(含AOP)
			//  调用Aware接口方法 -> 调用BeanPostProcessor.before方法 -> 调用init-method方法 ->  调用BeanPostProcessor.after方法
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			// 获取指定名称的已注册的单例bean
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				// 根据名称获取已注册的bean和正在实例化的bean是同一个
				if (exposedObject == bean) {
					// 当前实例化的bean初始完成
					exposedObject = earlySingletonReference;
				}
				// 当前bean依赖其他bean,且当发送循环引用时,不允许创建新的实例对象
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					// 获取当前bean所依赖的其他bean
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						// 对依赖bean进行类型检查
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// 注册完成依赖注入的bean
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

/**
	 * 初始化容器创建的bean实例对象,为其添加BeanPostProcessor后置处理器
	 * 调用Aware接口方法 -> 调用BeanPostProcessor.before方法 -> 调用init-method方法 ->  调用BeanPostProcessor.after方法
	 */
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		// 通过JDK的安全机制验证权限
		if (System.getSecurityManager() != null) {
			// 实现PrivilegedAction接口的匿名内部类
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 为bean实例对象包装相关属性,如名称、类加载器、所属容器等
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		// 调用BeanPostProcessor后置处理器的回调方法,在bean实例初始化前做一些处理
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 调用init方法 (@PostConstruct标注的init方法)
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 调用BeanPostProcessor后置处理器的回调方法,在bean实例初始化后做一些处理(AOP会在这一步实现代理对象)
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

/**
	 * 后置处理器:在bean初始化之后,init方法之后调用
	 */
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			// 依次执行BeanPostProcessor的postProcessAfterInitialization实现方法
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

 

我们看的有个applyBeanPostProcessorsAfterInitialization方法,会循环调用所有的BeanPostProcessor对当前bean做增强,如果这个bean配置了AOP代理的话,则会通AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization方法创建一个代理对象。我们来看一下其父类AbstractAutoProxyCreator的实现逻辑。

AbstractAutoProxyCreator#postProcessAfterInitialization方法
@Override
	public Object postProcessAfterInitialization(@Nullable 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;
	}

/**
	 * 如果有需要则包装一下当前bean
	 */
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		// 判断是否应该代理这个bean
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		/**
		 * 判断是否是一些InfrastructureClass或者是否应该跳过这个bean
		 * InfrastructureClass是指Advice、PointCut、Advisor等接口的实现类
		 */
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 获取这个bean的通知
		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;
	}

/**
	 * 创建代理对象
	 */
	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()) {
			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来创建的代理对象,调用getProxy就会返回CglibAopProxy或JdkDynamicAopProxy代理对象。

ProxyFactory#getProxy方法
public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

Spring源码-AOP部分-Spring是如何对bean实现AOP代理的

 

那么是怎么决定返回的是CglibAopProxy还是JdkDynamicAopProxy代理对象呢?是通过createAopProxy方法来决定的。

DefaultAopProxyFactory#createAopProxy方法
@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);
		}
	}

到此,一个代理对象就创建了出来。

 

上一篇:JavaScript 之 Proxy


下一篇:vue3--放大镜效果实现