目录
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and 确保此时真正解析了 bean 类,并且
// clone the bean definition in case of a dynamically resolved Class 在动态解析类的情况下克隆 bean 定义
// which cannot be stored in the shared merged bean definition. 不能存储在共享的合并 bean 定义中
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 2、验证及准备覆盖的方法
// Prepare method overrides.
mbdToUse.prepareMethodOverrides();
// 3、应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// AOP功能基于这里的判断,经过前置处理后返回的结果如果不为空,直接返回结果
if (bean != null) {
return bean;
}
// Central method of this class: creates a bean instance, populates the bean instance, applies post-processors, etc.
// 这个类的中心方法:创建一个bean实例,填充 bean 实例,应用后处理器等
return doCreateBean(beanName, mbdToUse, args);
}
1、resolveBeanClass()
锁定class,根据设置的class属性或者根据className 来解析 Class
/**
* Resolve the bean class for the specified bean definition, 解析指定bean定义的bean类,
* resolving a bean class name into a Class reference (if necessary) 将 bean 类名解析为类引用(如有必要)
* and storing the resolved Class in the bean definition for further use. 并将解析后的 Class 存储在 bean 定义中以供进一步使用。
* @param mbd the merged bean definition to determine the class for. 合并 bean 定义以确定类
* @param beanName the name of the bean (for error handling purposes). bean 的名称(用于错误处理目的)
* @param typesToMatch the types to match in case of internal type matching purposes. 在内部类型匹配的情况下要匹配的类型
* (also signals that the returned {@code Class} will never be exposed to application code) (也表明返回的 {@code Class} 永远不会暴露给应用程序代码)
* @return the resolved bean class (or {@code null} if none) 已解析的 bean 类(如果没有,则为 {@code null})
* @throws CannotLoadBeanClassException if we failed to load the class 如果我们加载类失败
*/
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
} else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader classLoaderToUse = beanClassLoader;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
classLoaderToUse = tempClassLoader;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
} else if (evaluated instanceof String) {
return ClassUtils.forName((String) evaluated, classLoaderToUse);
}
}
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (classLoaderToUse != beanClassLoader) {
return ClassUtils.forName(className, classLoaderToUse);
}
}
return mbd.resolveBeanClass(beanClassLoader);
}
2、prepareMethodOverrides()
对Override属性标记及验证
在 Spring 配置中存在 lookup - method 和 replace - method 两个配置功能,而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,这两个功能实现原理其实是在 bean 实例化的时候如果检测到存在 methodOverrides 属性,会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数。但是, Spring 将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证。
/**
* Validate and prepare the method overrides defined for this bean. 验证并准备为此 bean 定义的方法覆盖。
* Checks for existence of a method with the specified name. 检查具有指定名称的方法是否存在。
* @throws BeanDefinitionValidationException in case of validation failure
*/
public void prepareMethodOverrides(){
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
// MethodOverrides methodOverrides = new MethodOverrides();
// final Set<MethodOverride> overrides = new CopyOnWriteArraySet<>();
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
/**
* Validate and prepare the given method override.
* Checks for existence of a method with the specified name,
* marking it as not overloaded if none found.
* @param mo the MethodOverride object to validate
* @throws BeanDefinitionValidationException in case of validation failure
*/
protected void prepareMethodOverride(MethodOverride mo) {
// 获取对应方法名的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 1) {
// 标记 MethodOverrides 为未覆盖,避免参数类型检查的开销
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
3、resolveBeforeInstantiation()
实例化的前置处理
对后处理器中的所有 InstantiationAwareBeanPostProcessor 类型的后处理器 调用 postProcessBeforelnstantiation() 和 BeanPostProcessor 的 postProcessAfterInitialization()。
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the shortcut-determined bean instance, or {@code null} if none
*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
1)applyBeanPostProcessorsBeforeInstantiation()
在 bean 的实例化前会调用后处理器的方法进行处理
bean 的实例化前调用,也就是将 AbsractBeanDefinition 转换为 BeanWrapper 前的处理。
给子类一个修改 BeanDefinition 的机会,也就是说当程序经过这个方法后, bean 可能已经不是我们认为的 bean 了,而是或许成为了一个经过处理的代理 bean ,可能是通过 cglib 生成的,也可能是通过其他技术生成的。
/**
* Apply InstantiationAwareBeanPostProcessors to the specified bean definition
* (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
* <p>Any returned object will be used as the bean instead of actually instantiating
* the target bean. A {@code null} return value from the post-processor will
* result in the target bean being instantiated.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to use instead of a default instance of the target bean, or {@code null}
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
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;
}
2)applyBeanPostProcessorsAfterInitialization()
实例化后的后处理器应用
Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterlnitialization() 应用到该 bean 中,因为如果返回的 bean 不为空,那么便不会再次经历普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitialization()。
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}