ApplicationContext 和 BeanFactory
可以先简单了解下 ApplicationContext 和 BeanFactory。
详情见: https://blog.csdn.net/sinat_32502451/article/details/140247662
getBean() 代码示例
首先看代码示例,调试一下。
代码详情见: https://blog.csdn.net/sinat_32502451/article/details/140155044
public class MySpring {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("classpath*:mySpring.xml");//在 getBean 这一行,打个断点Person person = context.getBean("person", Person.class);System.out.println("=======>"+ person.getName());}}
BeanFactory 的 getBean() 源码:
public interface BeanFactory {//根据 bean 的名称,返回 bean对象.Object getBean(String name) throws BeansException;//根据 bean 名称,以及 匹配bean的类型,返回 bean对象.<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;}
bean 的作用域:
BeanFactory 中这两个方法,用于判断 bean 的作用域。
//作用域是否为单例模式?如果是, 每次调用 getBean()方法都会返回同一个对象。boolean isSingleton(String name) throws NoSuchBeanDefinitionException;//作用域是否为原型模式?如果是, 每次调用 getBean()方法都会返回不同的对象。boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
bean 对象的三级缓存:
bean 对象主要放在 map 里面,map 作为缓存。map 的key 是 bean对象的名称, value 是 bean 对象或者对象工厂。
Spring 使用了 三级缓存。
详情见:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
/** 第一级缓存,里面放置的是已经实例化好的单例对象 */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** 第二级缓存,里面存放的是提前曝光的单例对象 */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** 第三级缓存,里面存放的是将要被实例化的对象的对象工厂 */private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
添加 bean 对象到缓存中 :
- 创建 bean 对象,添加 到缓存的具体方法:
重点看下这几个方法。
org.springframework.context.support.AbstractApplicationContext#refresh
----> org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
----> org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
----> org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
----> org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
----> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
接下来会 实例化bean :
-----> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
-----> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
初始化 bean:
-----> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
添加 bean 对象到缓存:
----> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
获取 bean对象:
----> org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
----> org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
----> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
可以看到 实例化bean 、初始化 bean、 获取 bean对象, 都调用了 getBean() 方法。
getBean() 的具体实现:
重点看 getSingleton() 方法 和 createBean() 方法。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 检查单例缓存中是否有手动注册的单例Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 如果我们已经在创建这个bean实例,则失败// We're assumably within a circular reference.if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//检查此工厂中是否存在bean定义BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String 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 {return parentBeanFactory.getBean(nameToLookup, requiredType);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 保证初始化当前bean所依赖的beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {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 {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// 判断是否单例模式if (mbd.isSingleton()) {//获取单例模式的 bean,并添加到缓存中。这里可以重点看看。sharedInstance = getSingleton(beanName, () -> {try {//创建bean实例。。重点看看。return createBean(beanName, mbd, args);}catch (BeansException ex) {// 从单例缓存中删除实例destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// 如果是原型模式,就创建一个新的实例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;}}// 检查所需的类型是否与实际bean实例的类型匹配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.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}
创建 bean 对象:
关键看 实例化 bean 、 初始化 bean 。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}// 实例化 bean。 核心。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));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);// 初始化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 " +"'getBeanNamesOfType' 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;}
初始化bean:
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 {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
- 获取单例对象:
根据 bean 名称,返回已经注册的单例对象,
如果没有注册,则创建并注册一个新对象。
/*** 根据 bean 名称,返回已经注册的单例对象,如果没有注册,则创建并注册一个新对象。*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");//加同步锁synchronized (this.singletonObjects) {//根据 bean 名称,返回已经注册的单例对象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 {singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {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) {//前面介绍过, 如果是新的单例对象,此处将 bean 添加到 缓存中addSingleton(beanName, singletonObject);}}return singletonObject;}
}
- addSingleton() 方法:
如下, 将 bean 添加到 缓存中 :
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {//添加到缓存中。beanName值类似 上面的对象名"person" //singletonObject类似具体的对象 Person(age=1, name=Tom, fullName=null, dateOfBirth=null)this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}