• Spring Bean 生命周期(实例化过程)


    流程图

    实例化过程

    流程解释

    1. Bean容器找到配置文件中Spring Bean的定义。

    2. Bean容器利用Java Reflection API创建一个Bean的实例。

    3. 如果涉及到一些属性值,利用set()方法设置一些属性值。

    4. 如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。

    5. 如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。

    6. 如果Bean实现了BeanFactoryAware接口,调用setBeanClassFacotory()方法,传入ClassLoader对象的实例。

    7. 与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。

    8. 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法。

    9. 如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。

    10. 如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。

    11. 如果有和加载这个Bean的Spring容器相关的BeanPostProcess对象,执行postProcessAfterInitialization()方法。

    12. 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。

    13. 当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。

    代码

    doCreateBean

    	/**
    	 * Actually create the specified bean. Pre-creation processing has already happened
    	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
    	 * <p>Differentiates between default bean instantiation, use of a
    	 * factory method, and autowiring a constructor.
    	 * @param beanName the name of the bean
    	 * @param mbd the merged bean definition for the bean
    	 * @param args explicit arguments to use for constructor or factory method invocation
    	 * @return a new instance of the bean
    	 * @throws BeanCreationException if the bean could not be created
    	 * @see #instantiateBean
    	 * @see #instantiateUsingFactoryMethod
    	 * @see #autowireConstructor
    	 */
    	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    			throws BeanCreationException {
    
    		// Instantiate the bean.1.实例化bean
    		BeanWrapper instanceWrapper = null;
    		if (mbd.isSingleton()) {
    			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    		}
    		if (instanceWrapper == null) {
    			//实例化,开辟空间,属性都是默认值
    			instanceWrapper = createBeanInstance(beanName, mbd, args);
    		}
    		final Object bean = instanceWrapper.getWrappedInstance();
    		Class<?> beanType = instanceWrapper.getWrappedClass();
    		if (beanType != NullBean.class) {
    			mbd.resolvedTargetType = beanType;
    		}
    
    		// 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));
    		//如果是单例bean被提前暴露,那么将会加入三级缓存
    		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.//2.初始化bean实例的过程
    		Object exposedObject = bean;
    		try {
    			//2.1填充属性
    			populateBean(beanName, mbd, instanceWrapper);
    			//2.2初始化bean()
    			exposedObject = 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);
    					Set<String> 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;
    	}
    

    initializeBean

    	/**
    	 * Initialize the given bean instance, applying factory callbacks
    	 * as well as init methods and bean post processors.
    	 * <p>Called from {@link #createBean} for traditionally defined beans,
    	 * and from {@link #initializeBean} for existing bean instances.
    	 * @param beanName the bean name in the factory (for debugging purposes)
    	 * @param bean the new bean instance we may need to initialize
    	 * @param mbd the bean definition that the bean was created with
    	 * (can also be {@code null}, if given an existing bean instance)
    	 * @return the initialized bean instance (potentially wrapped)
    	 * @see BeanNameAware
    	 * @see BeanClassLoaderAware
    	 * @see BeanFactoryAware
    	 * @see #applyBeanPostProcessorsBeforeInitialization
    	 * @see #invokeInitMethods
    	 * @see #applyBeanPostProcessorsAfterInitialization
    	 */
    	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			//2.2.1调用bean 的 aware 方法
    			invokeAwareMethods(beanName, bean);
    		}
    
    		Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			//2.2.2初始化之前的增强处理,(如果某个类实现了BeanPostProcessor的话就用该类实现,没有就是用BeanPostProcessor的默认方法)
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    		try {
    			//2.2.3调用初始化方法
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    		if (mbd == null || !mbd.isSynthetic()) {
                            //2.2.4初始化之后的增强处理,(如果某个类实现了BeanPostProcessor的话就用该类实现,没有就是用BeanPostProcessor的默认方法)
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}
    
  • 相关阅读:
    js循环遍历弹框,先弹出第一个之后逐步弹出第二个。。
    js获取字符串的字节长度
    tomcat启动报错:Address already in use: JVM_Bind
    自整理的jquery.Validate验证表达式
    jerichotab 初始化页面显示tab页中的第一个
    POST提交大量数据,导致后面数据丢失
    IDEA启动时自动报Plugin Error错误
    apiCloud检出代码出现以下图示错误:
    javascript的一些在IE下不支持的函数小结
    The Nature of Recognition
  • 原文地址:https://www.cnblogs.com/yiweiblog/p/15005560.html
Copyright © 2020-2023  润新知