您的位置:首页 > 教育 > 培训 > spring框架4 - bean加载

spring框架4 - bean加载

2024/10/6 4:03:37 来源:https://blog.csdn.net/linping_wong/article/details/141830146  浏览:    关键词:spring框架4 - bean加载

本节内容:beanFactory.getBean("user");

    @Testvoid testGetBean() {Gun gun = beanFactory.getBean("m416", Gun.class);log.info("gun={}", gun);}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return this.doGetBean(name, requiredType, (Object[])null, false);
}
	/*** 返回指定bean的一个实例,该实例可以是共享的,也可以是独立的*/// eg1:name="m416",requiredType=Gun.class,args=null,typeCheckOnly=false@SuppressWarnings("unchecked")protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// 提取真正的beanName(去除‘&’或者将别名name转化为beanName)String beanName = transformedBeanName(name); // eg1:beanName="m416"/** 1:尝试根据beanName,从缓存中获得单例对象 */Object beanInstance, sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null)  // eg1:sharedInstance=nullbeanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); // 从bean中获得真正的实例对象/** 2:缓存中不存在实例,则采取自主创建实例对象 */else {// 如果当前bean是正在创建中的原型对象,则直接抛出异常if (isPrototypeCurrentlyInCreation(beanName)) // eg1:falsethrow new BeanCurrentlyInCreationException(beanName);/** 3:如果存在parentBeanFactory 并且 配置中也没有beanName的配置信息,则尝试从parentBeanFactory中获取实例 */BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // eg1:parentBeanFactory=nullString nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory)return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);else if (args != null)return (T) parentBeanFactory.getBean(nameToLookup, args);else if (requiredType != null)return parentBeanFactory.getBean(nameToLookup, requiredType);elsereturn (T) parentBeanFactory.getBean(nameToLookup);}// 如果不执行类型检查,则将beanName保存到alreadyCreated缓存中if (!typeCheckOnly) // eg1:truemarkBeanAsCreated(beanName);StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) // eg1:requiredType=Gun.classbeanCreation.tag("beanType", requiredType::toString);/** 4:将GenericBeanDefinition转换为RootBeanDefinition,如果是子Bean,则与父类的相关属性进行合并 */RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args); // eg1:mbd=RootBeanDefinition@2607/** 5:如果存在依赖,那么需要递归每一个依赖的bean并对其进行实例化创建 */String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) { // eg1:dependsOn=nullfor (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 {getBean(dep); // 创建每一个依赖(dep)的实例Bean}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}/** 6:创建bean的单例实例对象 */if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args); // eg1:return Gun@2334}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});// eg1:AbstractAutowireCapableBeanFactory#getObjectForBeanInstancebeanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}/** 7:创建原型对象 */else if (mbd.isPrototype()) {Object prototypeInstance;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}/** 8:创建指定scope类型的对象 */else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName))throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");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);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end(); // eg1:DefaultApplicationStartup#end()}}/** 9:检查需要的类型是否符合bean的实际类型,如果不同,则对其进行类型转换 */return adaptBeanInstance(name, beanInstance, requiredType); // eg1:return Gun@2334}

// 提取真正的beanName(去除‘&’或者将别名name转化为beanName)

// 提取真正的beanName(去除‘&’或者将别名name转化为beanName)
String beanName = transformedBeanName(name); // eg1:beanName="m416"
/*** 返回bean名称,必要时去掉工厂引用前缀,并将别名解析为规范名称*/
// eg1:name="m416"
protected String transformedBeanName(String name) {return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
/*** 返回实际的bean名称,去掉工厂解引用前缀(如果有,也去掉重复的工厂前缀)*/
// eg1:name="m416"
public static String transformedBeanName(String name) {Assert.notNull(name, "'name' must not be null");// 如果不是"&"前缀,则直接返回name即可if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) // eg1:truereturn name; // eg1:return "m416"// 去掉所有前缀"&",只返回beanNamereturn transformedBeanNameCache.computeIfAbsent(name, beanName -> {do {beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());}while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));return beanName;});
}
/*** 确定原始名称,将别名解析为规范名称*/
// eg1:name="m416"
public String canonicalName(String name) {String canonicalName = name;String resolvedName;do {// eg1:result = {ConcurrentHashMap@2355}  size = 5// 			"com.muse.springdemo.beanpostprocessor.MuseBeanPostProcessor" -> "com.muse.springdemo.beanpostprocessor.MuseBeanPostProcessor#0"// 			"org.springframework.web.servlet.view.InternalResourceViewResolver" -> "org.springframework.web.servlet.view.InternalResourceViewResolver#0"// 			"muse" -> "customUser"// 			"alias_ent" -> "ent"// 			"org.springframework.beans.factory.config.CustomEditorConfigurer" -> "org.springframework.beans.factory.config.CustomEditorConfigurer#0"/** 从别名中寻找原始名称 */resolvedName = this.aliasMap.get(canonicalName);if (resolvedName != null) // eg1:resolvedName=nullcanonicalName = resolvedName;}while (resolvedName != null);return canonicalName; // eg1:return "m416"
}

 


/** 1:尝试根据beanName,从缓存中获得单例对象 */
/** 2:缓存中不存在实例,则采取自主创建实例对象 */
    // 如果当前bean是正在创建中的原型对象,则直接抛出异常
    /** 3:如果存在parentBeanFactory 并且 配置中也没有beanName的配置信息,则尝试从parentBeanFactory中获取实例 */
    // 如果不执行类型检查,则将beanName保存到alreadyCreated缓存中
        /** 4:将GenericBeanDefinition转换为RootBeanDefinition,如果是子Bean,则与父类的相关属性进行合并 */
        /** 5:如果存在依赖,那么需要递归每一个依赖的bean并对其进行实例化创建 */
                // 如果发生了循环依赖,则直接抛出异常
        /** 6:创建bean的单例实例对象 */
        /** 7:创建原型对象 */
        /** 8:创建指定scope类型的对象 */
/** 9:检查需要的类型是否符合bean的实际类型,如果不同,则对其进行类型转换 */
 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com