看这篇文章以前能够先了解以前的跟踪流程,https://www.jianshu.com/p/4934233f0eadhtml
代码过宽,能够shift + 鼠标滚轮 左右滑动查看java
AbstractApplicationContext类refresh()方法中的第三个调用方法prepareBeanFactory()的跟踪。spring
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ... // Prepare the bean factory for use in this context. // 准备在上下文中bean factory的使用 prepareBeanFactory(beanFactory); ··· }
断点进入跟踪。express
此方法的实如今AbstractApplicationContext类中。缓存
/** * 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的方法app
此方法的实如今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? * <p>If the given name is an alias, it will be translated back to the corresponding * canonical bean name. * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot * be found in this factory instance. * <p>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的方法ide
此方法的实如今AbstractBeanFactory类中post
//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的方法this
此方法的实如今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<String> updatedSingletons = new LinkedHashSet<String>(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的方法
此方法的实如今DefaultSingletonBeanRegistry类中
//2.1调用父类方法,注册单例 super.registerSingleton(beanName, singletonObject); /** * Register the given existing object as singleton in the bean registry, * under the given bean name. * <p>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. * <p>When running within a full BeanFactory: <b>Register a bean definition * instead of an existing instance if your bean is supposed to receive * initialization and/or destruction callbacks.</b> * <p>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. * <p>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