上一篇文章分析到此处,接下继续进行后续的分析。
image.png来看一下,bdHolder是如何在BeanFactory中保存的,代码如下:
//registerBeanDefinition()方法的具体实现
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {
//获取beanName
String beanName = definitionHolder.getBeanName();
//使用beanName作为唯一标识注册
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
//如果解析的BeanDefinition有别名,也要根据别名在注册一遍,不然根据别名找不到相应的信息
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
//beanName -> alias ,先将alias转换为beanName,在查找
registry.registerAlias(beanName, alias);
}
}
}
最终承接注册任务方法是在DefaultListableBeanFactory类中定义的,为了更好的排版,我对下面的代码进行了删减,主要删除了抛出异常信息和日志信息,并不影响代码的逻辑,对于beanDefinition的注册,做了一些验证之后,直接将beanDefinition放入了Map中:
//向IoC容器注册解析的BeanDefiniton
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
//注册前的最后一次校验
//主要是对AbstractBeanDefinition属性中的methodOverrides校验
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
....
}
}
BeanDefinition oldBeanDefinition;
//检查是否有同名的beanName存在,判断allowBeanDefinitionOveriding属性
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw ...
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("....");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("....");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("...");
}
}
//如果允许覆盖则执行覆盖操作
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//判断是否已经有其他的Bean开始初始化
//在容器启动的最后会预初始化所有的singleton beans
if (hasBeanCreationStarted()) {
//注册的过程中需要线程同步,以保证数据的一致性
synchronized (this.beanDefinitionMap) {
//注册
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
//正常情况下应该走此分支
//将BeanDefinition放入Map中,此map中保存了所有的BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
//这个ArrayList中会按照bean配置的顺序保存每一个注册的Bean的名字
this.beanDefinitionNames.add(beanName);
//手动注册singleton bean
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
至此,Bean定义资源文件中配置的Bean被解析过后,已经注册到IoC容器中,被容器管理起来,真正完成了IoC容器初始化所做的全部工作。现 在IoC容器中已经建立了整个Bean的配置信息,这些BeanDefinition信息已经可以使用,并且可以被检索,IoC容器的作用就是对这些注册的Bean定义信息进行处理和维护。这些的注册的Bean定义信息是IoC容器控制反转的基础,正是有了这些注册的数据,容器才可以进行依赖注入。
最终,又回到了起点,便是如下这段代码:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//环境准备,获取容器启动的时间,设置活动标志,以及属性的初始化
prepareRefresh();
//在子类中启动resreshBeanfactory()方法
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//为BeanFactory配置容器属性
prepareBeanFactory(beanFactory);
try {
//设置BeanFactory的后置处理
postProcessBeanFactory(beanFactory);
//调用后置处理,为这些后置处理器在Bean的定义中向容器注册
invokeBeanFactoryPostProcessors(beanFactory);
//注册Bean的后续处理,在Bean创建过程中调用
registerBeanPostProcessors(beanFactory);
//初始化上下文消息机制
initMessageSource();
//初始化上下文中事件机制
initApplicationEventMulticaster();
//初始化其他特殊的Bean
onRefresh();
//检查监听Bean并且将这些Bean向容器注册
registerListeners();
//初始化所有的singleton beans , 设置lazy-init = true 的bean除外
finishBeanFactoryInitialization(beanFactory);
//发布容器事件,结束Refresh过程
finishRefresh();
}catch (BeansException ex) {
// 为防止Bean资源占用,在异常处理中,销毁已经生成的单件Bean
destroyBeans();
//重置Rest标志
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
其它的方法就不再多做解释了,主要介绍一下finishBeanFactoryInitialization(beanFactory); 由于spring默认是都是单例的,所以自定义的类会在此处进行初始化操作,接下来,看下主要进行了哪些操作。由于beanFactory作为参数传入了finishBeanFactoryInitialization方法中 ,最终起作用的是beanFactory.preInstantiateSingletons();由此方法进行类的实例化操作,看下主要的代码:
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.
//获取保存beanName的List
List<String> 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()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
上面代码很长,其实最终执行的只是getBean(beanName);这个方法。继续跟进,方法进入 AbstractBeanFactory 中
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
接下来将是攻坚战开始的地方,万里长征的第一步开始了。
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的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
//便不等bean创建完成就会将创建bean的ObjectFactory提早曝光
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回制定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//只有在单例的情况下,来解决循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中也就是所有已经加载的类中不包含beanName 则尝试从parentBeanFactory中检测
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);
}
}
//如果不是做类型检查,则是创建Bean,这里要记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final 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) {
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);
}
}
}
// Create bean instance.
//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()) {
// It's a prototype -> create a new instance.
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;
}
}
// Check if required type matches the type of the actual bean instance.
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.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
从代码量就能看出,bean的加载经历了一个非常复杂的过程,其中有各种情况的考虑,不过大致的步骤如下:
- 转换对应的beanName
- 尝试从缓存中加载单例: 此处有一个循环依赖的问题
- bean的实例化
- 原型模式的依赖检查
- 检测parentBeanFactory
- 将xml配置文件GernericBeanDefinition转换为RootBeanDefinition
- 寻找依赖
- 针对不同的scope进行bean的创建
- 类型转换
为了控制篇幅,本篇文章就到这把。 后面才是梦开始的地方。我会详细分析一下。
网友评论