Spring之实例化AOP标签的所有剩余的(非延迟-init)单例。

上一节中我们走了一遍有关bean的后置处理器的创建流程,大体上和以往创建bean的过程还是差不多的,接下来,我们就看一下剩下的单例是如何被加载的,这里还涉及了AOP的实例化。

finishBeanFactoryInitialization(beanFactory);

这行代码是我们本文的的入口函数:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//初始化此上下文的转换服务。
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// 如果没有bean后处理器,注册一个默认的内嵌值解析器(例如PropertyPlaceholderConfigurer bean)以前注册过:此时,主要用于解析注释属性值。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		//尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// 停止使用临时类加载器进行类型匹配。
		beanFactory.setTempClassLoader(null);
		//允许缓存所有bean定义元数据,不希望有进一步的更改。
		beanFactory.freezeConfiguration();
		// 实例化所有剩余的(非延迟-init)单例。
		beanFactory.preInstantiateSingletons();
	}

这个方法中我们最关心的代码是最后一行代码,我们进入这个方法,一部分一部分的看:

		//得到配置文件中所有的bean定义
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 触发所有非惰性单例bean的初始化…
		for (String beanName : beanNames) {
			//得到bean的定义
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//判断是否是抽象方法,是否是单例,是否是延迟加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					..
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

这个方法根据bean的定义进行判断选择不同的方式进行实例化,在这里遍历到的第一个beanName是userDao,我们接下来找一下和之前创建bean有什么不同。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd);

这个方法在我们之前遇到的解析bean返回的都是空,这次在进去看一下:

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		//选择可以用来实例化bean的处理器来实例化bean
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

果真和以前有一些不同,由于和AOP牵扯到了一起,所有这个bean就由AOP的处理前实例化了,继续看一下:

Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);

最终处理器调用了上面这个方法来实例化bean:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		//为要实例化的bean生成一个缓存的key
		Object cacheKey = getCacheKey(beanClass, beanName);
		
		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//看一下是不是已经被缓存过了
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}
		...
	}

下面这个方法也很重要:

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// 获取advisor列表
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//遍历advisor列表,如果和advisor切面引用的名称相同应该跳过
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor) {
				if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
					return true;
				}
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}

这个方法是用来确定当前bean是不是应该被略过,到这还是有点懵的,我们继续往下走,看看会发生什么,进入方法findAdvisorBeans:

String[] advisorNames = null;
		synchronized (this) {
			advisorNames = this.cachedAdvisorBeanNames;
			if (advisorNames == null) {
				// 在IOC中查找所有Advisor类的advisor的名字
				advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Advisor.class, true, false);
				this.cachedAdvisorBeanNames = advisorNames;
			}
		}
		if (advisorNames.length == 0) {
			return new LinkedList<>();
		}

这段代码就是查找所有指定类型的advisor

List<Advisor> advisors = new LinkedList<>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					...
				}
				else {
					try {
						//在advisors列表中添加创建好的advisor
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
						throw ex;
					}
				}
			}
		}

这段代码是遍历我们查找到的advisor的名字,如果当前advisor正在创建则不处理,否则就先实例化当前的advisor,再添加到IOC容器中。在当前我们的配置文件的定义中,一共两个advisor的定义,分别是用来在方法执行前执行,在方法执行后执行,接下来看一下advisor是如何被创建:
它也是按照实例化bean的流程过来的,又执行到了这个方法

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

但是这次由于advisor对应的class对象是InfrastructureClass,什么也没发生,返回的是null,所以程序又进入了doCreateBean方法,但这次没有直接调用无参构造方法去实例化对象,而是调用了下面这个方法来实例化对象:

autowireConstructor(beanName, mbd, ctors, args);

我们进入这个方法来看一下发生了什么事情:

protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}

很显然,创建了一个构造方法解析器并且调用了它解析有参构造函数创建对象的方法,autowireConstructor这个方法大约有200行代码,所以我们只能一行一行的分析了,是不是感觉这有点不想Spring的编程风格了呢,以往我们看到的都是把一个大的逻辑分解成一个一个小的逻辑,没办法了,我们还是继续看吧:

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);
		//可用的构造方法
		Constructor<?> constructorToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		//可用的构造函数的参数列表
		Object[] argsToUse = null;

一开始创建了一个封装bean定义的对象并将它进行初始化

若getBean方法调用时指定了方法参数,则直接使用
if(explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			 // 若getBean方法调用时没有指定方法参数,则尝试从配置文件中加载
			Object[] argsToResolve = null;
			// 对mbd的构造函数加锁
			synchronized (mbd.constructorArgumentLock) {
				//获取可以使用的构造函数
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				//如果获取到了可以使用的构造函数并且构造函数的参数已经解析
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// 获取解析的构造函数的参数
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						//若从缓存中没有解析出参数,那么就从配置文件中获取
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				//解析配之文件中的参数
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}

这段代码主要就是从缓存中获取可以使用的构造函数,如果获取到了,就从缓存中去解析参数,没有解析到参数就到配置文件中去解析,如果没有从缓存中获取到可以使用的构造函数,那么这段代码什么也不做,执行下面这段代码:

if (constructorToUse == null) {
	...
}

同样,我们一段一段的来分析:

// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
		minNrOfArgs = explicitArgs.length;
}
else {
		// 提取配置文件中的配置的构造函数参数
		ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
		 // 用于承载解析后的构造函数参数的值
		resolvedValues = new ConstructorArgumentValues();
		//解析配置文件中的参数 
		minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

我们来仔细看一下这个方法:

resolveConstructorArguments(...)
//获得类型转换器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
//判断转换器是不是为空
TypeConverter converter = (customConverter != null ? customConverter : bw);
//实例化一个值解析器
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
//获取参数的个数
int minNrOfArgs = cargs.getArgumentCount();

这段代码是获取了类型转换器并且获取到了构造方法中的参数的个数

//这段代码是解析按照标号指定构造参数的方式
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
			//获取下标
			int index = entry.getKey();
			if (index < 0) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid constructor argument index: " + index);
			}
			//真实的构造方法的参数比我们获得最小构造方法的参数要大
			if (index > minNrOfArgs) {
				minNrOfArgs = index + 1;
			}
			//获得当前下标的构造参数,这是被封装过的
			ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
			//如果被解析过了,那么直接添加
			if (valueHolder.isConverted()) {
				resolvedValues.addIndexedArgumentValue(index, valueHolder);
			}
			else {
			   //没有解析过,需要解析
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder =
						new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
			}
		}

这段代码是解析按照标号指定构造参数的方式

for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
			if (valueHolder.isConverted()) {
				resolvedValues.addGenericArgumentValue(valueHolder);
			}
			else {
				Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addGenericArgumentValue(resolvedValueHolder);
			}
		}

这段是按照自然顺序解析构造方法的参数。我们关心的是这个方法:

Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());

解析参数,我们进入看一下发生了什么:

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		...	
		else if (value instanceof BeanDefinition) {
			// Resolve plain BeanDefinition, without contained name: use dummy name.
			BeanDefinition bd = (BeanDefinition) value;
			String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
					ObjectUtils.getIdentityHexString(bd);
			return resolveInnerBean(argName, innerBeanName, bd);
		}
		...	
	}

这个方法在我们之前解析循环依赖问题的时候仔细讲过,只不过这次进入了另外一个分支

private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
		RootBeanDefinition mbd = null;
		try {
			//一个经过合并的bean定义
			mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition);
			// 检查给定的bean名称是否惟一。如果不是唯一的,添加计数器-增加计数器的值,直到名称是唯一的。
			String actualInnerBeanName = innerBeanName;
			if (mbd.isSingleton()) {
				actualInnerBeanName = adaptInnerBeanName(innerBeanName);
			}
			//在IOC容器中记录内部bean
			this.beanFactory.registerContainedBean(actualInnerBeanName, this.beanName);
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					this.beanFactory.registerDependentBean(dependsOnBean, actualInnerBeanName);
					this.beanFactory.getBean(dependsOnBean);
				}
			}
			// 实例化内部bean
			Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
			if (innerBean instanceof FactoryBean) {
				boolean synthetic = mbd.isSynthetic();
				innerBean = this.beanFactory.getObjectFromFactoryBean(
						(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
			}
			if (innerBean instanceof NullBean) {
				innerBean = null;
			}
			return innerBean;
		}
		...
	}

这个方法内部获得了一个合并的内部bean定义,并将这个内部bean进行实例化,实例化过程也基本是一样的,我们只看不同的地方:

for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
			...
		}

这次在解析构造参数的时候进入的是以下标索引的参数解析,我们还是要看循环内的和新方法:

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		...	
		else if (value instanceof BeanDefinition) {
			// Resolve plain BeanDefinition, without contained name: use dummy name.
			BeanDefinition bd = (BeanDefinition) value;
			String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
					ObjectUtils.getIdentityHexString(bd);
			return resolveInnerBean(argName, innerBeanName, bd);
		}
		...	
	}

又进入了这个分支中的代码,无非就是在按照创建内部bean的流程在走一遍(查找构造函数,解析构造方法,解析构造参数…),重复代码我们不看了:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			...
			else {
				//使用cglib策略创建实例
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

这次进入了使用默认构造方法实例化bean的方法,这个方法在之前过bean实例化的博客中提到过,执行完这个方法我们就得到了一个实例化好的内部bean,递归了这么多次,我们已经忘记了这个bean到底是哪个bean,是用来做什么的,没办法,我们继续跟进看看有什么线索:
在这里插入图片描述
到填充完属性之后我们发现,原来这个内部bean封装了<aop:before/>这个标签内部的method这个参数啊,继续解析下一个构造参数:
在这里插入图片描述
发现这次解析的是<aop:before/>这个标签内部的pointcut-ref这个参数,还有一个构造参数没有解析会是什么呢,继续跟进:
在这里插入图片描述
原来这个内部bean封装了userAop的名字,现在所需要的构造参数全都具备了,看一下接下来会发生什么:
在这里插入图片描述
之后就是根据我们选择的构造函数对我们获得到的构造参数进行排序

argsHolderToUse.storeCache(mbd, constructorToUse);

之后这一步将我们解析好的构造函数进行缓存

beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);

实例化当前这个内部bean的,大家不要搞混了,这已经到了第一层的内部bean了,第二层的内部bean作为第一层内部bean的构造参数已经全被解析完了。
在这里插入图片描述
这一层的内部bean已经是实例化完全的<aop:before/>了,第一层的内部bean也是一个构造参数啊,我们看看它参与创建了那个bean
在这里插入图片描述
这下清楚了,原来是一个前置通知器。

advisors.add(this.beanFactory.getBean(name, Advisor.class));

好了,绕了一大圈终于回来了,将创建好的一个前置通知器添加到通知器列表中,还有一个通知器没有创建,应该就是那个后置通知器吧,我们不看过程了,直接看结果来验证我们的猜想:
在这里插入图片描述
和我们猜想相符合,两个通知器全部创建结束了。

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor) {
				if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
					return true;
				}
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}

又回到这个方法了,接下来的工作就是看一下当前bean是否对应着我们处理过的通知器的构造参数,若有,那么略过这个bean的创建,因为我们在创建通知器的时候已经将这个bean创建完成并添加到缓存中了。很显然,这个bean是userDao,和我们的通知器的创建还没有关系,所以它还是要被创建的:

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

userDao在创建过程中,这行代码就被创建完成了,他总共看了这么几件事:
1、选择适合的后置处理器处理
2、处理之前看这个bean是不是需要被略过实例化
3、再检查被略过实例化的过程中,需要查找所有的通知器
4、在查找通知器的过程中,如果通知器还没有没创建,就要先创建通知器,期间涉及到了切面函数的创建,所以要检查当前需要被实例的bean是否属于一个切面bean,因为他已经在创建通知器的时候被创建了
5、所有通知器查找结束之后,验证当前bean是否是切面bean
6、是则略过创建,如果不是,则按照普通bean的流程创建
好了,到这个地方userDao可以按照正常的流程创建了,我们再来找不同,毕竟我们为他添加了AOP啊:

exposedObject = initializeBean(beanName, exposedObject, mbd);

这行代码成了我们关注的重点,就是在userDao在实例化和填充完属性之后,需要对他进行初始化,我们进去看一下这个方法,之前也没有讲过它:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		...

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//前置处理器初始化
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//执行初始化的方法
			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()) {
			//后置处理器初始化
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

这个方法内部主要做了三件事,初始化后置处理器,初始化前置处理器,执行初始化方法,在我们当前的配置中,我们最应该关心的是初始化后置处理器,因为它有和AOP有关的处理器:

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;
	}

我们一眼就看到了这个方法

wrapIfNecessary(bean, beanName, cacheKey);

应该就是创建一个代理类了,我们走进去具体看一下:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		...

		// 获取拦截器
		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;
	}

这个方法完成了代理的创建和返回

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

首先就是要获取和当前bean相关的所有advisor,我们走进去看一下是如何获取到的

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

很显然,方法内又调用了另一个方法:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//获取到所有的advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//获取和当前bean有关的advisor
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		//增加一个ExposeInvocationInterceptor在所有可使用的advisor开头
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

这个方法就是找到所有可用于当前bean的advisor,并且添加一个ExposeInvocationInterceptor拦截器在开头。
接下来要看一下代理是如何被创建的:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
		//如果可能的话,公开指定bean的给定目标类。
		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 {
				//检查给定bean类上的接口,并将其设置到proxyFactory上
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		//获得用于该bean的advisor
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		//设置到proxyFactory上
		proxyFactory.addAdvisors(advisors);
		//设置目标类
		proxyFactory.setTargetSource(targetSource);
		//交给用户来实现的自定义方法
		customizeProxyFactory(proxyFactory);
		//设置这个配置是否应该被冻结。
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		//创建目标类的代理类
		return proxyFactory.getProxy(getProxyClassLoader());
	}

这个方法实际上是创建了一个创建代理的工厂,给他设置上了一些属性,真正开始创建代理类是他的一个方法getProxy(),下面进入他看一下:

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,看之后的操作:

public Object getProxy(@Nullable ClassLoader classLoader) {
		//获得目标类需要被代理的接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

这个方法的最后一句是实例化这个代理类:

 public static Object newProxyInstance(ClassLoader loader,  Class<?>[] interfaces,   InvocationHandler h)  throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * 获得代理类的class对象
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
			//根据构造参数选择构造方法
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            //实例化代理类
            return cons.newInstance(new Object[]{h});
        } 
    }

就这样,针对目标类的代理类就被创建完成了,并加他添加到了缓存中。
剩下的bean都按照正常流程创建完成并添加到缓存中,好了,到这解析就全部结束了,下一篇文章我们将介绍aop是如何执行的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值