prepareBeanFactory方法源码跟踪

看这篇文章之前可以先了解之前的跟踪流程,https://www.jianshu.com/p/4934233f0ead

代码过宽,可以shift + 鼠标滚轮 左右滑动查看

AbstractApplicationContext类refresh()方法中的第三个调用方法prepareBeanFactory()的跟踪。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        ...
        // Prepare the bean factory for use in this context.
        // 准备在上下文中bean factory的使用
        prepareBeanFactory(beanFactory);
        ···
 }

断点进入跟踪。

此方法的实现在AbstractApplicationContext类中。

prepareBeanFactory(零)

/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
*
* 配置工厂的标准上下文特征,比如上下文的ClassLoader和post-processors
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    // Tell the internal bean factory to use the context's class loader etc.
    //告知内部的bean工厂,使用上下文的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    
    //设置bean表达式解析器,
    //StandardBeanExpressionResolver内部expressionParser属性默认SpelExpressionParser类型
    //spel = spring el表达式
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
    //将ResourceEditorRegistrar实例添加到工厂的propertyEditorRegistrars属性中,
    //propertyEditorRegistrars是一个LinkedHashSet,里面的元素将会应用到工厂bean中
    //ResourceEditorRegistrar持有上下文和environment的引用
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    // 使用上下文回调配置bean 工厂
    //在工厂的beanPostProcessor属性中添加处理器,beanPostProcessor是一个ArrayList
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    //在工厂的ignoredDependencyInterfaces属性中添加Aware系列接口,
    //ignoredDependencyInterfaces是一个HashSet
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    
    // 在普通的工厂中,BeanFactory接口并没有按照resolvable类型进行注册
    // MessageSource被注册成一个Bean(并被自动注入)
    
    //BeanFactory.class为key,beanFactory为value放入到了beanFactory的resolvableDependencies属性中
    //resolvableDependencies是一个ConcurrentHashMap,映射依赖类型和对应的被注入的value
    //这样的话BeanFactory/ApplicationContext虽然没有以bean的方式被定义在工厂中,
    //但是也能够支持自动注入,因为他处于resolvableDependencies属性中
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    
    //再将上下文的一些接口与上下文本身做映射,一一放入到resolvableDependencies中
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    // 检测LoadTimeWeaver,如果有就准备织入
    //1.跟踪进入,浅看下containsBean方法
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        
        //如果有LoadTimeWeaver,加入bean后处理器
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        
        // Set a temporary ClassLoader for type matching.
        // 为匹配类型设置一个临时的ClassLoader
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    // 注册默认的environment beans
    
    // 判断目前这个bean工厂中是否包含指定name的bean,忽略父工厂
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        
        //虽然XmlWebApplicationContext中持有默认实现的StandardServletEnvironment
        //但是没有注册到beanFactory中,通过getEnvironment方法拿到持有的引用
        //2.注册environment单例
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        
        //注册systemProperties单例
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        
        //注册systemEnvironment单例
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

1.containsBean

跟踪标记为1的方法

此方法的实现在AbstractBeanFactory类中

//1.跟踪看下containsBean方法
beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)

    
/**
* Does this bean factory contain a bean definition or externally registered singleton
* instance with the given name?
* 

If the given name is an alias, it will be translated back to the corresponding * canonical bean name. *

If this factory is hierarchical, will ask any parent factory if the bean cannot * be found in this factory instance. *

If a bean definition or singleton instance matching the given name is found, * this method will return {@code true} whether the named bean definition is concrete * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true} * return value from this method does not necessarily indicate that {@link #getBean} * will be able to obtain an instance for the same name. * * bean工厂是否包含一个给定name的bean definition,或者外部被注册的单例bean? * 如果name是一个别名,会被转换成对应的beanName * 如果工厂是有层级的,那么当工厂实例中找不到这个bean时,就会去父工厂中查找 * 如果找到匹配name的bean definition或者单例,那么这个方法会返回true * 不管这个bean definition是具体的还是抽象的,提前加载还是懒加载,是否在范围中。 * 因此,注意从这个方法中返回的true值并不代表从getBean方法中能够获取一个同名称的实例 */ @Override public boolean containsBean(String name) { //1.1对name进行必要的转换 String beanName = transformedBeanName(name); //singletonObjects或者beanDefinitionMap中已注册beanName则进入条件 //说明该beanName有对应的bean definition,或者单例bean if (containsSingleton(beanName) || containsBeanDefinition(beanName)) { //name开头不为&返回true,如果带了&但是是FactoryBean也返回true //要注意下FactoryBean和BeanFactory的区别,可以看下文参考链接 return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name)); } // Not found -> check parent. // 如果没有找到对应beanName的bean或者bean definition,那么从父工厂查找 BeanFactory parentBeanFactory = getParentBeanFactory(); return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name))); }

1.1 transformedBeanName

跟踪标记为1.1的方法

此方法的实现在AbstractBeanFactory类中

//1.1对name进行必要的转换
String beanName = transformedBeanName(name);

/**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
*
* 返回bean name,剥离factory dereference 前缀,并将别名解析为bean name
*/
protected String transformedBeanName(String name) {
    
    //总的来说,如果name代表factory,那么name前就带有&前缀,去掉此前缀
    //如果这个name是beanName,则直接返回,如果name是alias,在aliasMap中查找对应的beanName,再返回
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

//先看下transformedBeanName方法的实现
//进入BeanFactoryUtils类中
/**
* Return the actual bean name, stripping out the factory dereference
* prefix (if any, also stripping repeated factory prefixes if found).
*
* 返回真实的beanName,剥离工厂前缀(如果有的话,也剥离重复的工厂前缀)
*/
public static String transformedBeanName(String name) {
    Assert.notNull(name, "'name' must not be null");
    String beanName = name;
    //FACTORY_BEAN_PREFIX常量为:&
    while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
        beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
    }
    return beanName;
}


//再进入canonicalName方法查看
//此方法在SimpleAliasRegistry中实现,被默认bean工厂间接继承
/**
* Determine the raw name, resolving aliases to canonical names.
*
* 确定原生的name,将别名解析为BeanName
*/
public String canonicalName(String name) {
    String canonicalName = name;
    
    // Handle aliasing...
    // 处理别名
    String resolvedName;
    do {
        
        //拿到canonicalName对应的实际名称
        resolvedName = this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
            canonicalName = resolvedName;
        }
    }
    
    //只有当canonicalName在aliasMap中对应的value为null时,才跳出循环
    //这时候说明canonicalName已经不作为其他任何BeanName的别名,排除了间接引用
    //canonicalName就为真正的beanName
    while (resolvedName != null);
    return canonicalName;
}

2.registerSingleton

跟踪标记为2的方法

此方法的实现在DefaultListableBeanFactory类中

//2.注册environment单例
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());


@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
    
    //2.1调用父类方法,注册单例
    super.registerSingleton(beanName, singletonObject);

    //AbstractBeanFactory类中有个集合属性alreadyCreated
    //里面保存在至少被创建过一次的beanName
    //如果这个集合中存在beanName,那么说明已经进入了bean创建阶段
    if (hasBeanCreationStarted()) {
        
        // Cannot modify startup-time collection elements anymore (for stable iteration)
        // 无法再修改启动时集合元素(为了稳定迭代)
        synchronized (this.beanDefinitionMap) {
            
            //beanName不在beanDefinitionMap中,说明是手动注册
            if (!this.beanDefinitionMap.containsKey(beanName)) {
                Set updatedSingletons = new LinkedHashSet(this.manualSingletonNames.size() + 1);
                updatedSingletons.addAll(this.manualSingletonNames);
                updatedSingletons.add(beanName);
                this.manualSingletonNames = updatedSingletons;
            }
        }
    }
    else {
        
        // Still in startup registration phase
        // 仍然处于启动注册阶段
        if (!this.beanDefinitionMap.containsKey(beanName)) {
            
            //属于手动注册情况
            //environment属于手动注册单例
            this.manualSingletonNames.add(beanName);
        }
    }
    
    //进入这个方法查看
    clearByTypeCache();
}


/**
* Remove any assumptions about by-type mappings.
*
* 删除按照类型映射有关的任何假设
*/
private void clearByTypeCache() {
    
    //allBeanNamesByType是单例和非单例beanName的映射,key是依赖类型
    this.allBeanNamesByType.clear();
    
    //仅单例beanName的映射,key是依赖类型
    this.singletonBeanNamesByType.clear();
}

2.1 registerSingleton

跟踪标记为2.1的方法

此方法的实现在DefaultSingletonBeanRegistry类中

//2.1调用父类方法,注册单例
super.registerSingleton(beanName, singletonObject);


/**
* Register the given existing object as singleton in the bean registry,
* under the given bean name.
* 

The given instance is supposed to be fully initialized; the registry * will not perform any initialization callbacks (in particular, it won't * call InitializingBean's {@code afterPropertiesSet} method). * The given instance will not receive any destruction callbacks * (like DisposableBean's {@code destroy} method) either. *

When running within a full BeanFactory: Register a bean definition * instead of an existing instance if your bean is supposed to receive * initialization and/or destruction callbacks. *

Typically invoked during registry configuration, but can also be used * for runtime registration of singletons. As a consequence, a registry * implementation should synchronize singleton access; it will have to do * this anyway if it supports a BeanFactory's lazy initialization of singletons. * * 在给定的bean name下,将存在的对象作为单例注册在工厂中 * 给定的实例应该是完全初始化;工厂不执行任何初始化回调(特别是,他不会调用InitializingBean的 * afterPropertiesSet方法) * 给定的实例也不接收任何销毁回调(像DisposableBean的destroy方法) * 当在完整的BeanFactory运行时: * 如果你的bean需要接收初始化或者销毁的回调,注册一个bean definition替代一个存在的实例 * 通常此方法在工厂配置时被调用,也能在运行时单例注册时被调用。 * 作为结果,工厂的实现应该同步单例的访问;如果支持BeanFactory的单例的延迟初始化就不得不这样做 */ @Override public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { Object oldObject = this.singletonObjects.get(beanName); //不能注册两次 if (oldObject != null) { throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); } //进入这个方法 addSingleton(beanName, singletonObject); } } /** * Add the given singleton object to the singleton cache of this factory. *

To be called for eager registration of singletons. * * 添加给定单例对象到工厂的单例缓存中 * 用来被提早注册的单例调用 */ protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { //singletonObjects是一个ConcurrentHashMap //用来缓存单例对象 this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); //singletonFactories是一个HashMap //里面缓存着单例工厂 this.singletonFactories.remove(beanName); //早期单例对象 //earlySingletonObjects是一个HashMap this.earlySingletonObjects.remove(beanName); //registeredSingletons是一个LinkedHashSet //被注册单例的集合,以注册的顺序包含着bean name this.registeredSingletons.add(beanName); } }

这样,整个prepareBeanFactory方法也就跟踪完毕了。

接下来跟踪postProcessBeanFactory方法:
https://www.jianshu.com/p/c05aea93b939

参考

BeanFactory和FactoryBean的区别:https://www.cnblogs.com/aspirant/p/9082858.html

总结

  • 为工厂设置类的加载器、表达式解析器、属性编辑器注册器等
  • 为工厂添加后处理器、要忽略的依赖接口
  • 在工厂中注册可解析的依赖
  • 在工厂中提前注册一些单例Bean

你可能感兴趣的:(prepareBeanFactory方法源码跟踪)