@Override publicvoidinit(){ registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser()); registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser()); registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser()); registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser()); registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser()); registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser()); registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser()); }
protectedvoidaddPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader){ RandomValuePropertySource.addToEnvironment(environment); new Loader(environment, resourceLoader).load(); }
voidload(){ FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY, (defaultProperties) -> { this.profiles = new LinkedList<>(); this.processedProfiles = new LinkedList<>(); this.activatedProfiles = false; this.loaded = new LinkedHashMap<>(); initializeProfiles(); while (!this.profiles.isEmpty()) { Profile profile = this.profiles.poll(); if (isDefaultProfile(profile)) { addProfileToEnvironment(profile.getName()); } load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false)); this.processedProfiles.add(profile); } load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true)); addLoadedPropertySources(); applyActiveProfiles(defaultProperties); }); }
privatevoidinitializeProfiles(){ // The default profile for these purposes is represented as null. We add it // first so that it is processed first and has lowest priority. this.profiles.add(null); // Set<Profile> activatedViaProperty = getProfilesFromProperty(ACTIVE_PROFILES_PROPERTY); Set<Profile> includedViaProperty = getProfilesFromProperty(INCLUDE_PROFILES_PROPERTY); List<Profile> otherActiveProfiles = getOtherActiveProfiles(activatedViaProperty, includedViaProperty); this.profiles.addAll(otherActiveProfiles); // Any pre-existing active profiles set via property sources (e.g. // System properties) take precedence over those added in config files. this.profiles.addAll(includedViaProperty); addActiveProfiles(activatedViaProperty); if (this.profiles.size() == 1) { // only has null profile for (String defaultProfileName : this.environment.getDefaultProfiles()) { Profile defaultProfile = new Profile(defaultProfileName, true); this.profiles.add(defaultProfile); } } }
privatevoidinitializeProfiles(){ // The default profile for these purposes is represented as null. We add it // first so that it is processed first and has lowest priority. this.profiles.add(null); // 通过 spring.profiles.active 激活的配置 Set<Profile> activatedViaProperty = getProfilesFromProperty(ACTIVE_PROFILES_PROPERTY); // 通过spring.profiles.include 激活的配置 Set<Profile> includedViaProperty = getProfilesFromProperty(INCLUDE_PROFILES_PROPERTY); // 不是上面两个配置内的 但是目前是激活状态的配置 List<Profile> otherActiveProfiles = getOtherActiveProfiles(activatedViaProperty, includedViaProperty); this.profiles.addAll(otherActiveProfiles); // Any pre-existing active profiles set via property sources (e.g. // System properties) take precedence over those added in config files. this.profiles.addAll(includedViaProperty); addActiveProfiles(activatedViaProperty); if (this.profiles.size() == 1) { // only has null profile for (String defaultProfileName : this.environment.getDefaultProfiles()) { Profile defaultProfile = new Profile(defaultProfileName, true); this.profiles.add(defaultProfile); } } }
/** * Detect the validation mode for the XML document in the supplied {@link InputStream}. * Note that the supplied {@link InputStream} is closed by this method before returning. * @param inputStream the InputStream to parse * @throws IOException in case of I/O failure * @see #VALIDATION_DTD * @see #VALIDATION_XSD */ publicintdetectValidationMode(InputStream inputStream)throws IOException { // Peek into the file to look for DOCTYPE. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try { boolean isDtdValidated = false; String content; while ((content = reader.readLine()) != null) { content = consumeCommentTokens(content); if (this.inComment || !StringUtils.hasText(content)) { continue; } if (hasDoctype(content)) { isDtdValidated = true; break; } if (hasOpeningTag(content)) { // End of meaningful data... break; } } return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD); } catch (CharConversionException ex) { // Choked on some character encoding... // Leave the decision up to the caller. return VALIDATION_AUTO; } finally { reader.close(); } }
@SuppressWarnings("deprecation")// for Environment.acceptsProfiles(String...) protectedvoiddoRegisterBeanDefinitions(Element root){ // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // We cannot use Profiles.of(...) since profile expressions are not supported // in XML config. See SPR-12458 for details. if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isDebugEnabled()) { logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } }
public class MyNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("user", new UserBeanDefinitionParser()); } }
// Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } // 返回对应的实例,有时候存在BeanFactory的情况下不是直接返回实例本身而是返回BeanFactory指定方法返回的实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 只有在单例模式的情况下才解决循环依赖,如果是原型模式的话就直接抛错。 if (isPrototypeCurrentlyInCreation(beanName)) { thrownew BeanCurrentlyInCreationException(beanName); }
// Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); 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); } elseif (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } elseif (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); }
// Guarantee initialization of beans that the current bean depends on. // 比方说 a dependsOn b,b dependsOn c String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { thrownew BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { thrownew BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } }
// Create bean instance. // @Depends的都创建好了,可以创建自己了 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); }
// Don't let calling code try to dereference the factory if the bean isn't a factory. // 如果name里面有& 说明要的就是FactoryBean 那么我们直接返回FactoryBean 就好了 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } // 虽然name有& 但是Bean的类型不是FactoryBean 那么一定是出错了 if (!(beanInstance instanceof FactoryBean)) { thrownew BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance; }
// Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. // 如果bean的name里面没有& 并且 bean instance 也不是FactoryBean的实现 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } // 第三种情况 就是name 是没有& 但是得到的BeanDefinition是FactoryBean Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { //private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16); // 查看根据bean 那么是不是已经找到了RootBeanDefinition 如果不是的话 构建RootBeanDefinition // 根据Bean object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
getMergedLocalBeanDefinition
AbstractBeanFactory#getMergedLocalBeanDefinition
要把BeanDefinition 转化为RootBeanDefinition
1 2 3 4 5 6 7 8 9
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName)throws BeansException { // Quick check on the concurrent map first, with minimal locking. // 已经merge 好了 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
// Check with full lock now in order to enforce the same merged instance. if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } // 是不是已经被转换成了RootBeanDefinitions了,如果不是 继续转换流程 if (mbd == null || mbd.stale) { previous = mbd; if (bd.getParentName() == null) { // Use copy of given root bean definition. if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try { String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); } else { BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } else { thrownew NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without a ConfigurableBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { thrownew BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } // Deep copy with overridden values. mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd); }
// Set default singleton scope, if not configured before. if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(SCOPE_SINGLETON); }
// A bean contained in a non-singleton bean cannot be a singleton itself. // Let's correct this on the fly here, since this might be the result of // parent-child merging for the outer bean, in which case the original inner bean // definition will not have inherited the merged outer bean's singleton status. if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); }
// Cache the merged bean definition for the time being // (it might still get re-merged later on in order to pick up metadata changes) if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } } if (previous != null) { copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } }
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory){ Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { thrownew 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 + "'"); } //同样的讲beanName放到 singletonsCurrentlyInCreation 中 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 由ObjectFactory创建完成 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. 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) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); }
// 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.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } elseif (!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()) { thrownew 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."); } } } }
// Initialize message source for this context. // 初始化应用消息广播器 initMessageSource(); // Initialize event multicaster for this context. //初始化应用消息广播器 initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. // 留给子类来初始化其他的Bean onRefresh();
// Check for listener beans and register them. // 在所有注册的bean中查找Listener Bean,注册到广播中 registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. // 初始化剩下的单实例 finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. // 完成刷新过程,通知生命周期处理器 finishRefresh(); }
protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory){ // Tell the internal bean factory to use the context's class loader etc. // 设置classLoader beanFactory.setBeanClassLoader(getClassLoader()); // 设置beanFactory的语言表达式 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks. // 增加BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略自动装配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. // 自动装配的特殊规则 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found. // 增加@AspectJ的支持 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
// Register default environment beans. // 添加默认的Bean if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
// BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. // 自动装配的特殊规则 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
(define (fun-iter n cur a b c) (cond (((= n 1) 1) ((= n 2) 2) ((= n 3) 3) ((= n cur) a) (else (fun-iter n (+ cur 1) (+ (* a 3) (* b 2) c) a b) ) (define (func n) (fun-iter n 3321) )
练习 1.12
1 2 3 4 5 6
(define (pascal row col) cond ( (> col row) (error"unvalid col value") ((or (= col 0) (= col row)) 1) (+ pascal((- row 1) col) pascal((- row 1) (+ col 1))) ) )
(define (factorial n) (fact-iter11 n)) (define (fact-iter p b e) (if (> b e) p (fact-iter (* p b)(+ b 1) e)) ) (define (pascal row col) (/ (factorial row) (* (factorial col) (factorial (- row col)))
更相减损术
1 2 3
(define (gcb a b) (if (=0 b) a ( gcb b (remainder a b) ) )
实例 1.2.6 素数检测
1 2 3 4 5 6 7 8 9 10
(define (devides? a b) (= (remainder a b) 0) (define (smallest-divisor n) (find-divisor n 2)) (define (find-devisor n b) (conds ((> (square b) n)) n) ((devides? n b) b) (else (find-deversior n (+ b 1)) )
这些指令用于创建对象、锁定他们、检测他们的类型,等等。 NEW type 指令将一个type类型的新对象压入栈中
字段
这些指令读或者写一个字段的值。GETFIELD ower name desc 弹出一个对象引用,并将name字段中的值压入栈中。PUTFIELD owner name desc 弹出一个值和一个对象引用,并且将这个值存储在它的name字段中。在这两种情况下,该对象都必须是owner类型,它的字段必须是desc类型。GETSTATIC和PUTSTATIC是类似的指令
方法
这些指令调用一个方法或构造器。它们弹出值的个数等于其方法参数个数 + 1(用于目标对象),并压回方法调用的结果。 INVOKEVIRTUREAL owner name des调用在类owner中定义的name方法,其方法描述符为desc。INVOKESTATIC 用于静态方法,INVOKESPECIAL用于私有方法和构造器。INVOKDYNAMIC用于动态方法调用机制