今天这节内容我们一起来研究下,spring的bean的创建,我们一步步看着源码往下分析.下面的方法就会带我们进入bean的创建
完成bean工厂初始化
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化类型转换器,这一部分的内容,就是说,当前端传过来的数据类型后台不好解析,可以通过这个实现这个接口来实现类类型转换
//最典型的应用就是data转换
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));
}
// 初始化 LoadTimeWeaverAwareBean 用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//将临时类加载器设置为null
beanFactory.setTempClassLoader(null);
// 在初始化单例bean的过程中,先暂停bean的注册,解析加载等等
beanFactory.freezeConfiguration();
//初始化非懒加载的bean
beanFactory.preInstantiateSingletons();
}
其他方法都比较简单,咱们就直接从最后一个方法分析吧,这里干货满满哈
#DefaultListableBeanFactory
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//将所有的bean定义名称添加到beanNames集合中
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历所有的费懒加载的bean
for (String beanName : beanNames) {
//对bean定义进行合并,比如bean中引入属性parent这一步就是来处理这个属性的
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//如果bean不是抽象的,不是懒加载的,并且是单例的,执行以下步骤
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否是工厂bean
if (isFactoryBean(beanName)) {
//如果是工厂bean,调用的时候再bean的名称前面添加前缀符号&
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//再次判断bean是否是factoryBean
if (bean instanceof FactoryBean) {
final FactoryBean factory = (FactoryBean) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
//再次遍历beanNames,对实现了SmartInitializingSingleton接口的类实现处理,这里也就是说,他的功能类似于InitzationBean合格接口
//在单例bean加载完成后,做一些事情
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
//以上的方法都比较简单,我们总结下
1:遍历所有的非懒加载的bean
2:对bean属性中添加了paren的属性执行合并处理
3:判断某个bean是否是工厂bean,如果是,则在bean名称前面添加前缀&再执行处理
4:再次遍历bean,查看bean是否实现了SmartInitializingSingleton,如果实现该接口,在进行回调处理,类似于有点像InitzationBean这个接口
接下来,我们看这个方法中重复出现的一个方法,getBean,没错,就是他,这才是我们要研究的重点,我们一起看看这个方法
代码比较长,我们需要一步步分析啊
AbstractBeanFactory
@Override
public Object getBean(String name) throws BeansException {
//主要逻辑在dogetBean中
return doGetBean(name, null, null, false);
}
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//规范bean名称,就是说,你如果给bean起了别名,我们获取bean的时候,也能找见,这一步就是执行这个操作的
final String beanName = transformedBeanName(name);
Object bean;
// 检查是否已经创建了一个bean实例
Object sharedInstance = getSingleton(beanName);
//如果args不为为null,则证明是直接根据beanName获取bean,最终会走到getObjectForBeanInstance
if (sharedInstance != null && args == null) {
//1.1通过bean实例获取bean对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//如果args不为空,则执行以下逻辑,执行创建bean的逻辑
else {
//检查当前这个bean是否正在创建,如果正在创建,则直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查容器中是否已经存在了当前这个bean
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//不存在,证明当前容器中不存在这个bean,再去父容器中查看有没有
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
如果args不为null直接返回父容器的结果
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
//如果指定了bean的类类型,在args不为空的情况下,直接返回bean实例
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//从父容器获取一个bean直接返回
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//这里的typeCheckOnly默认就是false,这里的操作是将当前bean标记为已创建或将要创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//合并bean定义一级检查bean定义
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 获取当前bean的依赖,就是spring的属性depneds-on这个属性配置了这个属性全部放入dependsOn数组中
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//执行遍历,并检查当前bean的依赖,如果存在循环依赖,直接抛出异常
//这里解释下,在spring中,如果A依赖于B,我们使用Autowird注解将B先加载,
//但是有个场景,是,B和A没有任何的依赖关系,我们还要让B先加载那,这个depends就起到作用了
//也就是说,spring的bean加载是没有指定顺序的,是随意加载,用这个来控制bean的先后加载顺序
//如果这里,在两个bean中都配置了相互让对方先加载,就会直接抛出异常
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册当前依赖
registerDependentBean(dep, beanName);
try {
//这里是个递归调用,去获取依赖项这个bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//这里,我们终于走到了创建bean的逻辑里,这里注意下,对于spring的不同的作用于,
//如果是单例的,就走这个逻辑
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean方法
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//如果抛出异常,直接销毁bean
destroySingleton(beanName);
throw ex;
}
});
//创建完bean之后,获取当前bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//如果当前bean的属性是Prototype,则走这个逻辑
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//其他三个作用域的处理逻辑
=====================================================================================
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
=====================================================================================
// 如果requiredType不为null,并且不是指定的当前bean的实例,则通过转化器处理,如果处理结果任然是null,直接
//抛出异常
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
//总结下以上步骤:
1:规范bean的名称,因为bean有可能被起了别名,所以不管是通过原bean还是通过别名,都能访问到
2:检查当前bean实例是否已经创建,如果创建了,而且args参数为null的时候,证明是获取bean,不是创建bean
3:如果args不为null,就执行创建bean的逻辑
4:检查当前容器中是否存在当前的bean,子容器不存在,在区父容器中查找,找到的话,直接返回当前bean
5:将当前bean设置为已创建或将要创建的状态
6:获取bean之间的依赖关系,注意,这里指的是depends-on属性的依赖关系,一定要记清楚,这个是对于两个没有关系的bean,这种依赖,是不允许相互依赖的
7:注册依赖关系,让被依赖项先初始化,存在相互依赖,直接抛出异常
8:对不不同的bean的作用域,执行不同的床架bean操作,singleten,prototype,(request,session,globle-session)
9:对于requiredType不为空的,又不和当前bean实匹配,使用转换器去处理,如果结果还是null,直接抛出异常
以上内容比较简答,我对getBean这个方法做了整体的分析,但是由于篇幅的限制对具体的获取bean和创建bean没有分析,获取bean和创建bean我将分为两章分别介绍!
thanks!