佛山网站建设永网,定制网站开发技术,企业邮箱号码,本地的网站建设文章目录 ①. getBean方法的入口-DefaultListableBeanFactory②. DefaultListableBeanFactory调用getBean③. 进入到doGetBean方法④. getSingleton三级缓存方法⑤. getSingleton()方法分析⑥. createBean创建对象方法⑦. 对象创建、属性赋值、初始化⑧. getBean最详细流程图 ①… 文章目录 ①. getBean方法的入口-DefaultListableBeanFactory②. DefaultListableBeanFactory调用getBean③. 进入到doGetBean方法④. getSingleton三级缓存方法⑤. getSingleton()方法分析⑥. createBean创建对象方法⑦. 对象创建、属性赋值、初始化⑧. getBean最详细流程图 ①. getBean方法的入口-DefaultListableBeanFactory
①. getBean方法的入口:在Spring中,getBean方法的入口通常位于BeanFactory或ApplicationContext接口的实现类中。最常见的是DefaultListableBeanFactory类,它是Spring容器的核心实现,如下是三个API
// 根据name获取bean
Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}// 根据name获取bean,如果获取到的bean和指定类型不匹配,则抛出异常
Override
public T T getBean(String name, ClassT requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);
}// 根据name获取bean,如果是一个有参构造器生成的bean,则将参数对象注入到构造器中
Override
public Object getBean(String name, Object... args) throws BeansException {return doGetBean(name, null, args, false);
}②. DefaultListableBeanFactory调用getBean
②. DefaultListableBeanFactory中先获取到所有的bean的名称,for循环调用getBean方法
DefaultListableBeanFactory类
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace(Pre-instantiating singletons in this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.ListString beanNames new ArrayList(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd getMergedLocalBeanDefinition(beanName);// 是非抽象的并且是单例的并且不是懒加载的if (!bd.isAbstract() bd.isSingleton() !bd.isLazyInit()) {// 如果是FactoryBean执行下面逻辑(如果是实现了FactoryBean,isFactoryBean的标识为true)if (isFactoryBean(beanName)) {Object bean getBean(FACTORY_BEAN_PREFIX beanName);// beanName beanNameif (bean instanceof FactoryBean) {FactoryBean? factory (FactoryBean?) bean;boolean isEagerInit;if (System.getSecurityManager() ! null factory instanceof SmartFactoryBean) {isEagerInit AccessController.doPrivileged((PrivilegedActionBoolean) ((SmartFactoryBean?) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit (factory instanceof SmartFactoryBean ((SmartFactoryBean?) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 不是FactoryBean执行下面逻辑,普通的单实例非懒加载beangetBean(beanName);}}}
}AbstractBeanFactory类
Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}③. 进入到doGetBean方法
③. 进入到doGetBean方法
transformedBeanName,处理别名BeanName、处理带符的工厂BeanName。getSingleton,先尝试从缓存中获取Bean实例,这个位置就是三级缓存解决循环依赖的方法(后面重点说)/fontgetObjectForBeanInstance,如果sharedInstance是普通的Bean实例,则下面的方法会直接返回。另外sharedInstance是工厂Bean类型,则需要获取getObject方法,可以参考关于FactoryBean的实现类。isPrototypeCurrentlyInCreation,循环依赖有三种,setter注入、多实例和构造函数,Spring只能解决setter注入,所以这里是Prototype则会抛出异常。getParentBeanFactory,父bean工厂存在,当前bean不存在于当前bean工厂,则到父工厂查找bean实例。mbd.getDependsOn,处理使用了depends-on注解的依赖创建bean实例。getBean(dep),加载depends-on依赖dep是depends-on缩写mbd.isSingleton(),创建单例bean实例,这里的sharedInstance getSingleton(beanName, () - {})很重要/fontmbd.isPrototype(),创建其他类型的bean实例
protected T T doGetBean(String name, Nullable ClassT requiredType, Nullable Object[] args, boolean typeCheckOnly)throws BeansException {//处理别名BeanName、处理带符的工厂BeanName,工厂beanName带了xxx 最后会变成xxxString beanName transformedBeanName(name);Object beanInstance;// Eagerly check singleton cache for manually registered singletons.// 先检查单实例bean缓存Object sharedInstance getSingleton(beanName);if (sharedInstance ! null args null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace(Returning eagerly cached instance of singleton bean beanName that is not fully initialized yet - a consequence of a circular reference);}else {logger.trace(Returning cached instance of singleton bean beanName );}}beanInstance getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//默认第一次获取组件都会进入到else环节,如果第一次获取肯定是没有的// Fail if were already creating this bean instance:// Were assumably within a circular reference.// 如果是一个多实例bean,抛出异常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 拿到整个bean工厂,拿到父工厂;看父工厂有没有,如果有从父工厂去获取 Check if bean definition exists in this factory.BeanFactory parentBeanFactory getParentBeanFactory();if (parentBeanFactory ! null !containsBeanDefinition(beanName)) {// Not found - check parent.String nameToLookup originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args ! null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType ! null) {// No args - delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {// 标记当前bean已经被创建,用来阻止多线程引用的markBeanAsCreated(beanName);}StartupStep beanCreation this.applicationStartup.start(spring.beans.instantiate).tag(beanName, name);try {if (requiredType ! null) {beanCreation.tag(beanType, requiredType::toString);}RootBeanDefinition mbd getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn mbd.getDependsOn();if (dependsOn ! null) {// 看有没有依赖其他Bean,如果有先获取其他的那个Beanfor (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);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, beanName depends on missing bean dep , ex);}}}// Create bean instance. 创建Bean试连if (mbd.isSingleton()) {sharedInstance getSingleton(beanName, () - {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});// 看当前bean是否是使用了beanFactorybeanInstance getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// Its a prototype - create a new instance.Object prototypeInstance null;try {beforePrototypeCreation(beanName);prototypeInstance createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}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();}}return adaptBeanInstance(name, beanInstance, requiredType);
}④. getSingleton三级缓存方法
④. Object sharedInstance getSingleton(beanName,第一次进来的时候,会直接返回null
一级缓存 - singletonObjects二级缓存 - earlySingletonObjects,当前bean已经创建,未进行实例化三级缓存 - singletonFactories,用来保存BeanName和创建bean的工厂之间的关系 /** * 一级缓存* Cache of singleton objects: bean name -- bean instance */private final MapString, Object singletonObjects new ConcurrentHashMap(256);/** * 三级缓存* 用来保存BeanName和创建bean的工厂之间的关系* Cache of singleton factories: bean name -- ObjectFactory */private final MapString, ObjectFactory? singletonFactories new HashMap(16);/** * 二级缓存* 保存BeanName和创建bean实例之间的关系,与singletonFactories的不同之处在于,当一个单例bean被放到这里之后,那么当bean还在创建过程中* 就可以通过getBean方法获取到,可以方便进行循环依赖的检测* Cache of early singleton objects: bean name -- bean instance */private final MapString, Object earlySingletonObjects new HashMap(16);public Object getSingleton(String beanName) { // allowEarlyReference 允许早期引用(循环依赖的核心)return getSingleton(beanName, true);}Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 先检查单列缓存池,获取当前对象 Quick check for existing instance without full singleton lockObject singletonObject this.singletonObjects.get(beanName);// 先看单例池有没有 并且 是否正在创建if (singletonObject null isSingletonCurrentlyInCreation(beanName)) {// 如果当前bean正在创建过程中,而且缓存中没有继续往下//singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject this.singletonObjects.get(beanName);if (singletonObject null) {singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null) {ObjectFactory? singletonFactory this.singletonFactories.get(beanName);if (singletonFactory ! null) {singletonObject singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}⑤. getSingleton()方法分析
⑤. public Object getSingleton(String beanName, ObjectFactory? singletonFactory)方法
beforeSingletonCreation(beanName)会将beanName加入到singletonsCurrentlyInCreation集合中去,表示正在创建的集合singletonFactory.getObject()会调用lamda表达式的内容[这里之后要进入lamda方法流程]afterSingletonCreation(beanName)会将当前beanName从singletonsCurrentlyInCreation中移除出去addSingleton方法会将当前bean加入到singletonObjects池中去 public Object getSingleton(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(beanName, Bean name must not be null);synchronized (this.singletonObjects) {Object singletonObject this.singletonObjects.get(beanName);if (singletonObject null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!));}if (logger.isDebugEnabled()) {logger.debug(Creating shared instance of singleton bean beanName );}beforeSingletonCreation(beanName);boolean newSingleton false;boolean recordSuppressedExceptions (this.suppressedExceptions null);if (recordSuppressedExceptions) {this.suppressedExceptions new LinkedHashSet();}try {// 会调用lamda表达式的内容singletonObject singletonFactory.getObject();newSingleton true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime -// if yes, proceed with it since the exception indicates that state.singletonObject this.singletonObjects.get(beanName);if (singletonObject null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions null;}afterSingletonCreation(beanName);}if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}⑥. createBean创建对象方法
⑥. 进入到createBean(beanName, mbd, args);lamda流程,最重要的是doCreateBean方法,进入到创建对象流程中 protected Object createBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// 提前给一个机会,去返回组件的代理对象(aop也没有在这里操作) Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean resolveBeforeInstantiation(beanName, mbdToUse);if (bean ! null) {return bean;}......Object beanInstance doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace(Finished creating instance of bean beanName );}return beanInstance;}⑦. 对象创建、属性赋值、初始化
⑦. doCreateBean方法详解
利用无参构造方法创建实例earlySingletonExposure表示:当前对象是单实列、并且singletonsCurrentlyInCreation中存在这个beanName,我们在上面的步骤中已经加入到了singletonsCurrentlyInCreation集合中了addSingletonFactory方法会将beanName加入到三级缓存singletonFactories中去populateBean进行属性的赋值,Autowired发生在这里initializeBean初始化bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper null;if (mbd.isSingleton()) {//是否单例instanceWrapper this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper null) {// 创建Bean的实列,默认使用无参构造创建对象instanceWrapper createBeanInstance(beanName, mbd, args);}Object bean instanceWrapper.getWrappedInstance();Class? beanType instanceWrapper.getWrappedClass();if (beanType ! NullBean.class) {mbd.resolvedTargetType beanType;}//允许MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition再来修改下BeanDefinition Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Post-processing of merged bean definition failed, ex);}mbd.postProcessed true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject bean;try {// 给创建好的对象每个属性进行赋值,Autowired发生在这里populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Initialization of bean failed, ex);}}if (earlySingletonExposure) {Object earlySingletonReference getSingleton(beanName, false);if (earlySingletonReference ! null) {if (exposedObject bean) {exposedObject earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping hasDependentBean(beanName)) {String[] dependentBeans getDependentBeans(beanName);SetString actualDependentBeans new LinkedHashSet(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,Bean with name beanName has been injected into other beans [ StringUtils.collectionToCommaDelimitedString(actualDependentBeans) ] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using getBeanNamesForType with the allowEagerInit flag turned off, for example.);}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Invalid destruction signature, ex);}return exposedObject;}protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(singletonFactory, Singleton factory must not be null);synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}⑧. getBean最详细流程图