一.doscan方法的补充:
01.在findCandidateComponents(basePackage)方法中:优化,因为扫描package
如果存在有索引的文件,使用索引文件来加载bean
public Set<BeanDefinition> findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);}}
这一段:
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}
这个和spring.components有关:(这个要自己创建)
spring.components文件内部如图:
代码会看这个文件的内容
02.addCandidateComponentsFromIndex方法:
private Set<BeanDefinition> addCandidateComponentsFromIndex(CandidateComponentsIndex index, String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {Set<String> types = new HashSet<>();for (TypeFilter filter : this.includeFilters) {// Component注解String stereotype = extractStereotype(filter);if (stereotype == null) {throw new IllegalArgumentException("Failed to extract stereotype from " + filter);}types.addAll(index.getCandidateTypes(basePackage, stereotype));}boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (String type : types) {MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type);if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setSource(metadataReader.getResource());if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Using candidate component class from index: " + type);}candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + type);}}}else {if (traceEnabled) {logger.trace("Ignored because matching an exclude filter: " + type);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;}
getCandidateTypes方法:
public Set<String> getCandidateTypes(String basePackage, String stereotype) {List<Entry> candidates = this.index.get(stereotype);if (candidates != null) {return candidates.parallelStream().filter(t -> t.match(basePackage)).map(t -> t.type).collect(Collectors.toSet());}return Collections.emptySet();}
运行:
二.合并beanDefinition:
01.这里看扫描之后的执行的函数,beanfactory.preInstantiateSingleton : 创建非懒加载的bean的方法
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.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {// 获取合并后的BeanDefinitionRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//bd.isAbstract(),这里判断 的是bean是不是有这个属性,不是类型是不是抽象类if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {// 获取FactoryBean对象Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {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) {// 创建真正的Bean对象(getObject()返回的对象)getBean(beanName);}}}else {// 创建Bean对象getBean(beanName);}}}// 所有的非懒加载单例Bean都创建完了后// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}}
02.开头是这一段
for (String beanName : beanNames) {// 获取合并后的BeanDefinitionRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);}
getMergedLocalBeanDefinition:
合并的BeanDefinition,这个和bean中的一个属性有关parent:
举例:
在xml文件中声明bean标签:
<bean id="user" class="com.xxx.xxx.User" Scope="prototype"></bean><bean id="userService" class="com.xxx.xxx.UserService" parent="user"></bean>
如果BeanDefinition中有parent属性的话(userService),就会去找这个parent(user)。然后合并两个BeanDefinition,形成一个新的bean,这个bean的类型是RootBeanDefinition 。就这个例子而言,会创建两个BeanDefinition,然后创建一个合并的RootBeanDefinition 。
getMergedLocalBeanDefinition具体方法:
这里的mergedBeanDefinitions是一个集合,用于存储RootBeanDefinition 。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {// 从集合中获取key值是beanName的RootBeanDefinition RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);if (mbd != null && !mbd.stale) {return mbd;}//如果没有相应的RootBeanDefinition return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
另一个的getMergedBeanDefinition方法:
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)throws BeanDefinitionStoreException {return getMergedBeanDefinition(beanName, bd, null);}
getMergedBeanDefinition方法:
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;RootBeanDefinition previous = null;// Check with full lock now in order to enforce the same merged instance.if (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);}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.// pbd表示parentBeanDefinitionBeanDefinition 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 {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.// 子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并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;}}
mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);