Spring源码(六)-创建Bean流程-createBean
createBean
方法总体可以分为四个小方法:
- resolveBeanClass:加载 Class 对象
- prepareMethodOverrides:对通过 XML 定义的 bean 中的
lookup-method
和replace-method
属性进行预处理 - resolveBeforeInstantiation:实例化前应用后处理器
- doCreateBean:创建 Bean
接下来就一个一个来看吧!
resolveBeanClass
首先调试进入AbstractAutowireCapableBeanFactory
类的createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 使用类加载器根据 class 或者根据 className 来加载 Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//省略代码...
}
进入AbstractBeanFactory
类中的resolveBeanClass
方法,注意typesToMatch
的类型可能为FactoryBean.class
,typesToMatch
是一个可变参数。自己再DeBug
的时候可以找找resolveBeanClass
方法在哪些地方被调用。
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
//BeanDefintion是在扫描的时候创建的,
//但是AbstractBeanDefinition中存在一个beanClass属性
try {
// 如果beanClass是Class,就直接返回beanClass
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
//忽略
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
// 加载AbstractBeanDefinition中beanClass中所指定的类名对应的类
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
进入 AbstractBeanFactory
类中的doResolveBeanClass
方法
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
// 拿到类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
// 获取BeanDefinition中所指定的beanClass属性的值,
String className = mbd.getBeanClassName(); // 字符串 或者 #{xxx}
if (className != null) {
// className可以是Spring EL表达式,所以需要解析
Object evaluated = evaluateBeanDefinitionString(className, mbd);
// 如果 className 是Spring EL表达式,className 与 evaluated 会不相等的
if (!className.equals(evaluated)) {
// evaluated 类型是Class 直接返回
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
// evaluated 类型是String 将 freshResolve 的值设置为 true
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
if (dynamicLoader != null) {
try {
// 使用类加载器加载类
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
// 反射工具类加载Class对象
return ClassUtils.forName(className, dynamicLoader);
}
}
// 反射工具类加载Class对象
return mbd.resolveBeanClass(beanClassLoader);
}
resolveBeanClass
方法就是通过来判断 AbstractBeanDefinition
类中的 beanClass
属性,如果是 Class
就直接返回,如果不是就获取 beanClass
属性的值并将它转换为 Stirng
类型,然后对 className
做表达式解析。最后通过dynamicLoader.loadClass(className)
加载 Class 对象,或者通过ClassUtils.forName(className, classLoader)
加载 Class 对象。
prepareMethodOverrides
对通过XML定义的bean中的lookup-method和replace-method属性进行预处理
try {
// 对通过XML定义的bean中的lookup-method和replace-method方法进行预处理
// 对于@Lookup注解标注的方法不在这里进行处理
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
进入AbstractBeanDefinition
类的prepareMethodOverrides
方法
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
//检查是否存在查找方法,并确定其重载状态。
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
进入AbstractBeanDefinition
类的prepareMethodOverride
方法
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
// 获取对应本类、父类、父接口中对应方法的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
//标记 overloaded 暂未被被盖 避免参数类型检查的开销
mo.setOverloaded(false);
}
}
该方法主要针对lookup-method
和replace-method
做预处理,现在这两个属性用得比较少了。如果对这两个属性有兴趣,可以在 Spring 的官网进行查看: 点我前往
也可以移步前往: Spring源码(二—2)-lookup-method、replaced-method元素
resolveBeforeInstantiation
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 1、实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 对象
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
注意上面方法中有个if
判断块,当经过前置处理后返回的结果如果不为空,那么会直接略过后续 bean 的创建而直接返回结果。当前 Bean 的创建流程结束,不会再往下执行 doCreateBean
函数。
进入 AbstractAutowireCapableBeanFactory
类的resolveBeforeInstantiation
方法
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved的值只会为null或true
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 返回 Class 对象
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;
}
然后进入 AbstractAutowireCapableBeanFactory
类的determineTargetType
方法,该方法就是将 Class 对象加载出来。
@Nullable
protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
// 获取resolvedTargetType属性,也相当于缓存,
Class<?> targetType = mbd.getTargetType();
if (targetType == null) {
// 如果BeanDefinition中设置了factoryMethodName,那么就通过factoryMethodName来判断类型,
// 否则获取AbstractBeanDefinition中的beanClass
targetType = (mbd.getFactoryMethodName() != null ?
getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
resolveBeanClass(mbd, beanName, typesToMatch));
if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
// 将解析出来的类型记录到resolvedTargetType中
mbd.resolvedTargetType = targetType;
}
}
return targetType;
}
AbstractAutowireCapableBeanFactory
类的applyBeanPostProcessorsBeforeInstantiation
实例化前方法
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行 postProcessBeforeInstantiation 方法,也就是 实例化前
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
注意:上述方法的方法名 applyBeanPostProcessors BeforeInstantiation,BeforeInstantiation
实例化前。首先获得所有的 BeanPostProcessor
,然后循环遍历判断是否实现了InstantiationAwareBeanPostProcessor
,然后执行 postProcessBeforeInstantiation
实例化前方法。如果 postProcessBeforeInstantiation
方法返回了对象,也就是不返回 null
,就执行 applyBeanPostProcessorsAfterInitialization
初始化后方法。
AbstractAutowireCapableBeanFactory
类的applyBeanPostProcessorsAfterInitialization
初始化后方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行postProcessAfterInitialization方法,也就是初始化后
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
也要注意该方法的方法名 applyBeanPostProcessorsAfterInitialization,AfterInitialization
初始化后。获取到所有的 BeanPostProcessor
,然后循环每个BeanPostProcessor
的postProcessAfterInitialization
初始化后方法。如果postProcessAfterInitialization
初始化后方法的返回值为 null
就直接结束循环,进行返回。比如我有三个 BeanPostProcessor
,A、B、C,在执行A BeanPostProcessor
的时候,A的postProcessAfterInitialization
方法返回了null
,B、C两个BeanPostProcessor
不会再执行。AOP 也在此进行执行。
如果对于 BeanPostProcessor
不熟悉的伙伴可以移步前往:Spring源码-BeanPostProcessor
doCreateBean
程序执行了 resolveBeforeInstantiation
函数之后,如果返回的结果为 null
,就需要执行 doCreateBean
函数进行创建 Bean。
try {
// 创建bean Spring自带的创建bean的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
doCreateBean
函数的篇幅太长,将拆分几篇文章进行阅读。
- 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。