下面是spring容器的启动代码
//引用配置文件
Resource resource = new ClassPathResource("spring.xml");
//创建bean工厂
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//解析配置,并注册bean到工厂中
BeanDefinitionReader context=new XmlBeanDefinitionReader(factory);
context.loadBeanDefinitions(resource);
//从工厂中取出对象
AdminUser user = (AdminUser) factory.getBean("admin");
System.out.println(user.getUsername());
1.Resource
Spring对其内部使用到的资源进行了自己的抽象结构:Resource接口来封装底层资源。
InputStreamSource封装任何能返回InputStream的类,比如File,Classpath下的资源和Byte Array等。
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Resource接口抽象了所有Spring内部使用到的底层资源:File,URL,ClassPath等。首先,定义了3个用于判断当前资源状态的方法。另外还提供了不同资源到URL,URI,File类型的转换,以及获取lastModified属性,文件名的方法。还提供了基于当前资源创建一个相对资源的方法;createRelative()。
public interface Resource extends InputStreamSource {
//是否存在
boolean exists();
//是否可读
boolean isReadable();
//是否处于打开的状态
boolean isOpen();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
//根据当前资源创建一个相对资源
Resource createRelative(String relativePath) throws IOException;
String getFilename();
//在错误处理中的打印信息
String getDescription();
}
2. XmlBeanDefinitionReader
- BeanDefinitionReader:主要定义资源文件读取并转换为 BeanDefinition 的各个功能
- EnvironmentCapable:定义获取Environment的方法
- AbstractBeanDefinitionReader:对 EnvironmentCapable 和 BeanDefinitionReader 定义的功能进行实现
ResourceLoader
:定义资源加载器,主要用于根据给定的资源文件地址返回对应的
- ResourceXmlBeanDefinitionReader对资源解析主体类
DocumentLoader
:定义从资源文件加载到转换为Document的功能BeanDefinitionParserDelegate
:定义解析 Element 的各种方法BeanDefinitionDocumentReader
:定义读取 Document 并注册 BeanDefinition 功能
Spring读取XML配置文件的大致流程主要为:
- XmlBeanDefinitionReader 通过继承 AbstractBeanDefinitionReader 中的方法,使用 ResourceLoader 将资源路径转换为对应的 Resource 文件;
- 通过 DocumentLoader 对 Resource 文件进行转换,将 Resource 文件转换为 Document 文件;
- 通过实现 BeanDefinitionDocumentReader 接口的 DefaultBeanDefinitionDocumentReader 类对 Document 进行解析,并使用 BeanDefinitionParserDelegate 对 Element 进行解析。
3.DefaultListableBeanFactory
AliaRegistry:
定义对别名(Alias)的简单增删改查
<alias name="admin" alias="bean2"></alias>
//注册
void registerAlias(String name, String alias);
//移除
void removeAlias(String alias);
//判断是否别名
boolean isAlias(String name);
//根据真实值获取别名
String[] getAliases(String name);
BeanDefinitionRegistry:
定义对BeanDefinition的各种增删改等操作。BeanDefinition就是Element的JAVA对象应射。主要有三种类型
//parent 类型
<bean id="animal" class="Animal" abstract="true"></bean>
<bean id="monkey" parent="animal"></bean>
//factory-bean
<bean id="bmwCar" class="CarStaticFactory" factory-method="getCar">
//class
<bean id="admin" class="entity.AdminUser" />
//如果没设置ID,其名字自动生成方式请教参
//BeanDefinitionReaderUtils.generateBeanName
//注册
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
//删除
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//获取
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//是否存在
boolean containsBeanDefinition(String beanName);
SimpleAliasRegistry:
主要使用map作为alias的缓存,并对接口AliasRegistry进行实现
//别名加真实的id的Map
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
SingletonBeanFactory:
定义对单例及获取的操作。
//注册
void registerSingleton(String beanName, Object singletonObject);
//获取
Object getSingleton(String beanName);
//是否存在
boolean containsSingleton(String beanName);
DefaultSingletonBeanRegistry:
对单例对象存储的默认实现, 对接口SingletonBeanFactory的实现。
//name-对象的存储
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//name-对象没经过set注入,装配中对象
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//name-对象工厂,没有经过构造的对象,没有装配的对象。懒加载
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//以上三个cache互斥,name统一保存在registeredSingletons
//对象的流转顺序
//1.singletonFactories->earlySingletonObjects->singletonObjects
//2.earlySingletonObjects->singletonObjects
//3.singletonObjects
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//提供直接注册singletonObjects接口
public void registerSingleton(String beanName, Object singletonObject);
//提供注册singletonFactories接口
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)
//提供查找接口
//一般情况下,只能查找singletonObjects
//当查找的对象isSingletonCurrentlyInCreation正在创建中,说明人家想拿出去装配,则查earlySingletonObjects
//当allowEarlyReference为true时,从singletonFactories->earlySingletonObjects
protected Object getSingleton(String beanName, boolean allowEarlyReference) ;
//记录当前正常创建的bean,如果出现循环依赖会发现
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//开后门排队一些类,永远不能通过singletonFactories创建
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//beanName是否正在创建
//bean不在inCreationCheckExclusions中且在singletonsCurrentlyInCreation
public boolean isCurrentlyInCreation(String beanName);
//标记beanName开始创建
//bean不在inCreationCheckExclusions,加入singletonsCurrentlyInCreation
protected void beforeSingletonCreation(String beanName)
//标识beanName结束创建
//bean不在inCreationCheckExclusions,移除singletonsCurrentlyInCreation
protected void afterSingletonCreation(String beanName)
//容器是否在销毁状态
private boolean singletonsCurrentlyInDestruction = false;
//没删对象销毁时的监听器DisposableBean
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
//从三大cache和registeredSingletons中移除
//并通知beanName监听器DisposableBean
public void destroySingleton(String beanName)
// 使用constructor-arg 的一种注入方式
// 关键字 Annotation-Base, XML-Base 表示 “我包含谁” 的关系
// 相当于依赖,现在基本上不使用
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
//key为对象- value 为被key所依赖的对象
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
//key为对象- value 是依赖key的对象
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
如何解决A依赖B,B依赖A的过程
- A初始化,创建FactoryObject<A>放入singletonFactories,发现要依赖B
- B初始化,发现要依赖A,从singletonFactories查找到A装载
- FactoryObject<A>调用其getObject方法,并提升至earlySingletonObjects缓存
- B初始化完成,继续A初始化
- A初始化完成,提升至singletonObjects
FactoryBeanRegistrySupport
:
在 DefaultSingletonBeanRegistry
的基础上增加对 FactoryBean 的特殊处理功能
//缓存的不是FactoryBean对象,而是FactoryBean单例模式下调用getObject()之后的返回结果
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
//从factory创建Object,如果factory是单例模式,且beanName在DefaultSingletonBeanRegistry存在,则缓存到factoryBeanObjectCache
//因为factory单例模式,也就是说明factory只会创建一个Object,因些是1对1关系
//所以把创建的Object管理到factoryBeanObjectCache中,beanName和factory在容器中相同
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)
BeanFactory:
定义不同条件获取bean的方式,及一些辅助方法。
//因为FactoryBean和其getObject名字一样,无法区分
//因此在名字前加上&表示要获取FactoryBean
//BeanFactoryUtils.isFactoryDereference判断是否取FactoryBean
String FACTORY_BEAN_PREFIX = "&";
//根据名字取
Object getBean(String name) throws BeansException;
//根据类型取
<T> T getBean(Class<T> requiredType) throws BeansException;
//是否单例
boolean isSingleton(String name)
//是否是期望的类型
boolean isTypeMatch(String name, ResolvableType typeToMatch)
//是否存在 singletonObjects 和 beanDefinitionMap 排除 FactoryBean对象
public boolean containsBean(String name)
HierarchicalBeanFactory
:
继承自 BeanFactory
接口,在其基础上增加对 parentFactory 支持
//返回父亲容器
BeanFactory getParentBeanFactory();
//是否存在,和containsBean区别,仅在当前容器中找,不查找父亲容器
boolean containsLocalBean(String name);
ConfigurableBeanFactory:
定义BeanFactory
的配置.比如类加载器,类型转化,属性编辑器,BeanPostProcessor
,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory
,bean如何销毁.
// 定义了两个作用域: 单例和原型.
// 单例,会存到DefaultSingletonBeanRegistry中
String SCOPE_SINGLETON = "singleton";
//原型,直接创建
String SCOPE_PROTOTYPE = "prototype";
//注册自动义作用域,可以根据需要在不同作用哉下面挂类似DefaultSingletonBeanRegistry的容器
//单例和原型默认实现,不可以注册,
void registerScope(String scopeName, Scope scope);
// 父容器设置.而且一旦设置了就不让修改
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 类加载器设置与获取.默认使用当前线程中的类加载器
void setBeanClassLoader(ClassLoader beanClassLoader);
//设置一个临时加载器,专门用于类型检查。主加载器不会为了类型检查加载类
//保证真实的加载器是懒加载。。
//容器所有类检测完成时,这个会被移除
//一般情况下这个为null,也就是主加载器也用于类型检测
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
//比如parent的bean,其需要通过合并属性才能得到真正的BeanDefinition
//当cacheBeanMetadata为true,合并一次后缓存下来,不需要重新计算
void setCacheBeanMetadata(boolean cacheBeanMetadata);
//Bean表达式分解器类似 #{...} 等 EL表达式
void setBeanExpressionResolver(BeanExpressionResolver resolver);
//类型转换器
void setConversionService(ConversionService conversionService);
//注册属性编辑器, 用于搭建xml中 property,和JAVA-bean的真实类型转换
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
// BeanFactory用来转换bean属性值或者参数值的自定义转换器
// 包装着ConversionService 和 PropertyEditor
void setTypeConverter(TypeConverter typeConverter);
//增加一字符串解析类
//现在默认代理是BeanExpressionResolver
//主要目地方便以后支持更多的表达式
void addEmbeddedValueResolver(StringValueResolver valueResolver);
//使用StringValueResolver解析字符串
String resolveEmbeddedValue(String value);
//设置一个Bean处理器
//BeanPostProcessor提供 bean init-method 方法调用前后的切入
//BeanPostProcessor before -> InitializingBean afterPropertiesSet -> bean init-method -> BeanPostProcessor after
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
// 访问权限控制
// 提升反射权限
public AccessControlContext getAccessControlContext()
//复制其它工厂的配置
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
//给指定的Bean注册别名
//@see SimpleAliasRegistry
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
//返回合并后的BeanDefinition
//@see setCacheBeanMetadata
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
AbstractBeanFactory
:
抽象类,综合 FactoryBeanRegistrySupport
和 ConfigurableBeanFactory
的功能
//大部份成员都体现在
//@see ConfigurableBeanFactory
// BeanPostProcessor是否存在 InstantiationAwareBeanPostProcessors
// InstantiationAwareBeanPostProcessors 主要是对BeanPostProcessor升级,增加切入对象构造方式
// InstantiationAwareBeanPostProcessors.postProcessBeforeInstantiation -> 对象构造 -> InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation
// InstantiationAwareBeanPostProcessors.postProcessProperties -> InstantiationAwareBeanPostProcessors.postProcessPropertyValues
private volatile boolean hasInstantiationAwareBeanPostProcessors;
// BeanPostProcessor是否存在DestructionAwareBeanPostProcessors
//BeanPostProcessor是否存在DestructionAwareBeanPostProcessors 主要是对BeanPostProcessor升级,增加切入对象销毁
//DestructionAwareBeanPostProcessors.postProcessBeforeDestruction -> 对象移出容器销毁
private volatile boolean hasDestructionAwareBeanPostProcessors;
// bean实例是否已创建
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//prototypes模式是否循环依赖的判断, 线程间相互独立所以用ThreadLocal
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation");
AutowireCapableBeanFactory:
解决Bean的依赖关系及提供Bean的生命周期
//会使用AdminUser中的属性名字,去容器中查找并装载,相当于注解方式@Resource(name="aa")
<bean id="admin" class="entity.AdminUser" autowire="byName" />
//会使用AdminUser中的属性类型,去容器中查找并装载,相当于注解方式@Autowired。
<bean id="admin" class="entity.AdminUser" autowire="byType" />
//使用AdminUser的构造器中的参数类型,去容器中查找,并装载(前提是没有默认构造器)
//因为在初始化环节,所以不支持循环依赖
<bean id="admin" class="entity.AdminUser" autowire="constructor">
//默认的手工指定的装载方式
//前面三种装载方式和此方式不产生互斥
<bean id="d1" class="entity.D1" init-method="yy" >
<property name="adminUser" ref="admin" />
</bean>
//注入List对象
<bean class="Grade" id="grade">
<property name="students">
<list>
<ref bean="student1"/>
<ref bean="student2"/>
<ref bean="student3"/>
</list>
</property>
</bean>
//其接口函数主要描述,bean的生命周期
阶段 PostProcessor 说明
实例化 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 实例化前准备可搞代理
createBeanInstance SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors MergedBeanDefinition提取构造器
autowireConstructor 有参构造器装配实例化
instantiateBean 无参构造实例化(与上面互斥)
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition 告知MergedBeanDefinition
属性装配 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 实例化后
populateBean autowireByName 根据名称装配
autowireByType 根据类型装配
InstantiationAwareBeanPostProcessor.postProcessPropertyValues 自定义属性装配
BeanDefinitionValueResolver.resolveValueIfNecessary 解析配置关联真实对象
初始化 BeanNameAware.setsetBeanName 根据实现不同的接口为对象不同的设置
initializeBean BeanClassLoaderAware.setBeanClassLoader
BeanFactoryAware.setBeanFactory
BeanPostProcessor.postProcessBeforeInitialization 切入通知代理初始化开始对象
InitializingBean.afterPropertiesSet 表示自定义初始化完成
<bean>的init-method 执行bean声明的init-method
beanProcessor.postProcessAfterInitialization 切入通知代理初始化结束对象
销毁 DestructionAwareBeanPostProcessor.postProcessBeforeDestruction 通知进行销毁
destroyBean DisposableBean.destory 自定义销毁
<bean>的destory-method 执行bean声明的destory-method
//默认
int AUTOWIRE_NO = 0;
//根据名字装载
int AUTOWIRE_BY_NAME = 1;
//根据类型装载
int AUTOWIRE_BY_TYPE = 2;
//根据构造装载
int AUTOWIRE_CONSTRUCTOR = 3;
// spring有约定,名字后面用此后缀的不允许代理对象
// @see #initializeBean(Object, String)
// @see #applyBeanPostProcessorsBeforeInitialization(Object, String)
// @see #applyBeanPostProcessorsAfterInitialization(Object, String)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
//根据类型获取对象
//经历 实例-装配-初始化
<T> T createBean(Class<T> beanClass) throws BeansException;
//根据具体实例获取对象
//经历 装配
void autowireBean(Object existingBean) throws BeansException;
//根据具体实例获取对象,并给它取个名
//经历 装配-初始化
Object configureBean(Object existingBean, String beanName) throws BeansException;
//根据类型获取对象,并指定装配模式,依赖检查
//经历 实例-装配-初始化
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
//根据class获取对象,并指定装配模式,依赖检查
//经历 实例-装配
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
//根据具体实例获取对象,并指定装配模式,依赖检查
//经历 装配
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
//根据实例对象的属性,关联真实对象
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
//初始化
Object initializeBean(Object existingBean, String beanName) throws BeansException;
//初始化前代理
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
//初始化后代理
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
//销毁对象
void destroyBean(Object existingBean);
//根据类型获取NamedBeanHolder
//@see #getBean(Class)
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
// 根据名字和类型获取实例
// @see #getBean(String, Class)
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
//根据名字和类型获取实例,
//如果类型是List,则会把列表填充入autowiredBeanNames
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
AbstractAutowireCapableBeanFactory
:
综合 AbstractBeanFactory
并对接口 AutowireCapableBeanFactory
进行实现
//代理对象的策略
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
//方法参数名的解析策略,编译方式的不同可能取其方法名称的方式不同
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
//是否开启自动解决bean的循环依赖
private boolean allowCircularReferences = true;
//是否允许依赖是代理对象不是实际对象
private boolean allowRawInjectionDespiteWrapping = false;
//自动装配时,对此属性类型忽略,如String
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>();
//自动装配时,对指定接口忽略,当前仅有BeanFactory
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
//辅助,将当前创建的bean注册为依赖
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
//返回代理用 BeanWrapper的FactoryBean
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();
//缓存类的对应方法数组
private final ConcurrentMap<Class<?>, Method[]> factoryMethodCandidateCache = new ConcurrentHashMap<>();
//缓存类的对应属性数组
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<>();
ListableBeanFactory:
根据各种条件获取bean的配置清单(列表)。
// 对于给定的名字是否含有BeanDefinition
boolean containsBeanDefinition(String beanName);
// 返回工厂的BeanDefinition总数
int getBeanDefinitionCount();
// 返回工厂中所有Bean的名字
String[] getBeanDefinitionNames();
// 根据类型获取bean
String[] getBeanNamesForType(ResolvableType type);
// 获取给定类型的bean 查找通过bean类型,子类及FactoryBean的getObjectType判断.
String[] getBeanNamesForType(Class<?> type);
//根据指定类型的名字(同上)
//includeNonSingletons为false表示只取单例Bean,true则不是
//allowEagerInit为true表示立刻加载,false表示延迟加载。 注意:FactoryBeans都是立刻加载的。
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
// 根据注解类型,查找所有有这个注解的Bean名和Bean的名字
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
// 根据指定Bean名和注解类型查找指定的Bean
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
ConfigurableListableBeanFactory
:
继承BeanFactory
配置清单,配置一些加载的特别场景
//自动装配autowire时,如果对象是忽略的类型,则不装配
void ignoreDependencyType(Class<?> type);
//自动装配autowire时,如果对象有包含忽略的接口,则不装配
void ignoreDependencyInterface(Class<?> ifc);
//如果是byType装载方式,byType可能找到多个对应的Bean. 提前注册此方式确立唯一性
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
//判断descriptor是否在Bean使用自动装配
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
//根据beanName获取BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//清理缓存下来的BeanDefinition
//@see #getBeanDefinition
//@see #getMergedBeanDefinition
void clearMetadataCache();
//暂时冻结所有的Bean配置,BeanDefinition不允许修改
//当被冻结时,BeanDefinition全部走MetadataCache
void freezeConfiguration();
// 预实例化所有非懒加载单例Bean
void preInstantiateSingletons() throws BeansException;
DefaultListableBeanFactory:
综合补全上面的所有功能。
//虚拟机内全局 serializationId - beanFactory映射
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<>(8);
//beanFactory的标识,可根据它在serializableFactories取出
private String serializationId;
//是否允许两个bean名字相同,如果不允许会报异常,允许则打日志替换
private boolean allowBeanDefinitionOverriding = true;
//是否允许懒加载 lazy-init
private boolean allowEagerClassLoading = true;
//依赖类型是List, 各依赖在List顺序的排序器
private Comparator<Object> dependencyComparator;
//提供依赖属性的自定处理逻辑,后期的@Qualifier注解以及@Value注解
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
//如果是byType装载方式,byType可能找到多个对应的Bean. 提前注册此方式确立唯一性
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
//存储name-BeanDefinition的
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//原型+单例模式的 type - names的映射缓存
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
//单例模式的 type - names的映射缓存
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
//beanDefinition的所有name集合
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
//通过手工手动注册的单例
//@registerSingleton
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
//冻结时,缓存的所有的Bean配置
private volatile String[] frozenBeanDefinitionNames;
//暂时冻结所有的Bean配置
private volatile boolean configurationFrozen = false;
Bean的加载
factory.getBean("admin")看起来这一简单的代码,引出一个血案
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly)
throws BeansException {
//提取对应的beanName
final String beanName = transformedBeanName(name);
Object bean;
//检查缓存中或者实例工厂中是否有对应的实例
//为什么首先会出现这段代码呢,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
//Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,
//一旦下个bean创建时候需要依赖上个bean则直接使用
//尝试从缓存获取或从singletonFactories中的ObjectFactory中获取
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 + "'");
}
}
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//只有在单例情况下才会尝试解决依赖循环,原型模式情况下,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候
//就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就是isPrototypeCurrentlyInCreation(beanName)
//为true
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//如果beanDefinitionMap中也就是在所有已经加载的类中不包括beanName则尝试从parentBeanFactory中检测
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);
}
}
//如果不是仅仅做类型检查则是创建bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition,
//如果指定BeanName是子Bean的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 若存在依赖则需要递归实例化依赖的bean
String[] 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);
}
}
}
//实例化依赖的bean后便可以实例化mbd本身了
//singleton模式的创建
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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//prototype模式的创建
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 {
//指定的scope上实例化bean
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;
}
1)转换对应的beanName
或许很多人不理解转换对应beanName是什么意思,传入的参数name不就是beanName吗?其实不一定,这里传入的name有可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,这些解析内容包括如下内容
i.去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&,而是name="aa"。
ii.取指定alias所表示的最终beanName,例如别名A指向名称为B的bean则返回B,若别名A指向别名B,别名B又指向名称为C的bean则返回C
(2)尝试从缓存中加载单例
单例在Spring的同一个容器内只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。当然这里也只是尝试加载,首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直使用ObjectFactory
(3)bean的实例化
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。这里有必要强调一下,缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean。举个例子,加入我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法返回的bean,而getObjectForBeanInstance就是完成这个工作的。
(4)原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖,如果存在A中有B属性,B中有A属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就是情况:isPrototypeCurrentInCreation(beanName)==true。
(5)检测parentBeanFactory
从代码上看,如果缓存没有数据的话直接转到父类工厂上去加载了,这是为什么呢?
可能我们忽略了一个很重要的判断条件:parentBeanFactory != null && !containsBeanDefinition(beanName),parentBean如果为空,则一切免谈,这个显而易见。但是containBeanDefinition(beanName)就比较重要了,它是检测如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试下了,然后再去递归的调用getBean方法。
(6)将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition。
因为从XML配置文件中读取到的Bean信息是存储在GenericBeanDefinition中的,但是所有的Bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。
(7)寻找依赖
因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以在Spring的加载顺序中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖。
(8)针对不同的scope进行bean的创建
我们都知道,在Spring中存在着不同的scope,其中默认的是singleton,但是还有些其他的配置诸如prototype、request、session之类的。在这个步骤中,Spring会根据不同的配置进行不同的初始化策略。
(9)类型转换
程序到这里返回bean后已经基本结束了,通常对该方法的调用参数requiredType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是requiredType却传入Integer类型,那么这个时候本步骤就会起作用了,他的功能是将返回的bean转换为requiredType所指定的类型。
总结
spring-beans更关注的是组件内部的一个问题。组件的一个生命周期,组件的依赖
主要参考
《spring-bean之AutowireCapableBeanFactory》