spring(详细步骤)
2022-06-23 11:51:24 39 举报
spring 部分源码眼瞎解决方案。 https://blog.csdn.net/qq_35483542/article/details/128325501
作者其他创作
大纲/内容
String beanName : this.manualSingletonNames
从缓存中获取getObject对象
类型转换和排序
如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
DefaultSingletonBeanRegistry
mbd = getMergedLocalBeanDefinition(beanName)
解析#{}el表达式
去获取一个bean不为空且不是空bean
当前BeanDefinition不是FactoryBean,就是普通Bean并且如果不包括单例并且mbd不是单例,则忽略该mbd最后进行类型匹配
不存在
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
对选出的配置类进行排序,然后进行遍历
获取所有内部类没有就返回
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :\t\t\t\tBeanUtils.instantiateClass(generatorClass));
想要注入BService
ClassPathScanningCandidateComponentProvider
isPrototypeCurrentlyInCreation(beanName)
isEagerInit = (factory instanceof SmartFactoryBean &&\t\t\t\t\t\t\t\t\t((SmartFactoryBean<?>) factory).isEagerInit())
!className.equals(evaluated)->evaluated instanceof Classreturn (Class<?>) evaluated->evaluated instanceof StringclassName = (String) evaluated; freshResolve = true;
// getImports(sourceClass)会拿到@Import导入的类\t\t// 如果导入的是普通类,那么会直接把它当做配置类来解析\t\t// 如果导入的是普通ImportSelector,那么会将返回的类再次调用processImports()\t\t// 如果导入的是特殊ImportSelector,DeferredImportSelector,那么暂时不会处理,会在解析完所有当前这轮配置类后进行导入,将返回的类再次调用processImports()\t\t// 如果导入的是ImportBeanDefinitionRegistrar,那么暂时不会处理,会在解析完所有当前这轮配置类后,将配置类解析成为BeanDefinition之后进行调用
是否以饥饿模式创建,非懒加载
如果缓存中不存在就直接实例化一个bean
初始化
获取scope并设置,处理@Lazy、@Primary、@DependsOn、@Role、@Description处理传参的qualifiers数组进行解析@lazy与@primary
beanFactory.setBeanClassLoader(getClassLoader());-> if (!shouldIgnoreSpel) { beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); }
Object beanInstance = font color=\"#b71c1c\
如果beanName 对应的bean没有被创建过
BeanWrapperImpl bw = new BeanWrapperImpl();\t\tthis.beanFactory.initBeanWrapper(bw)
if (!advised.isInterfaceProxied(SpringProxy.class)) { proxiedInterfaces.add(SpringProxy.class); } if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) { proxiedInterfaces.add(Advised.class);} if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) { proxiedInterfaces.add(DecoratingProxy.class);}
parentBeanFactory != null && !containsBeanDefinition(beanName)
查看对应的mdb是否存在解析后的缓存如果缓存只是一部分的信息或者需要进一步解析那么就进行进一步解析
this.factoryBeanObjectCache.get(beanName)
去单例池中查找没有找到并且AService正在被创建,说明出现循环依赖
如果对应的applicationcontext继承于abstractRefreshApplicationContext就可以重复刷新,而继承于genericApplicationContext只能刷新一次
处理特殊beanName防止FactoryBeanName出现多个‘&’(&&xxx)
返回当前的bean工厂
如果不是上面的特殊类型就直接获取如果还是获取不到,并且require为true就报错了
factoryBeanName != null
查看注解中require属性是否必须注入如果必须注入时又无对应bean注入将报错最后构建注入点并放入集合中
SingletonObject
先执行子类(BeanDefinitionRegistryPostProcessor)的postProcessBeanFactory然后执行父类(BeanFactoryPostProcessor)的postProcessBeanFactory
二级缓存不存在就去查找三级缓存
candidate.setScope(scopeMetadata.getScopeName());
创建代理对象
(4)
this.lifecycleProcessor.onClose()
this.beanFactory = new DefaultListableBeanFactory();
如果field是静态的时候将不进行注入并return
ParameterNameDiscoverer.getParameterNames(candidate)->argsHolder = font color=\"#b71c1c\
if (beanFactory instanceof BeanDefinitionRegistry)->for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors)-> (true)registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor);-> (false)regularPostProcessors.add(postProcessor);
简单描述
检查扫描出来的BeanDefinition是不是配置类(full和lite)如果是配置类解析这个扫描出来的类
checkForCircularImports && isChainedImportOnStack(configClass)
!beanName.equals(parentBeanName
加入ClassUtils是被Bootstrap类加载器加载的,则获取系统类加载器
解析依赖对象
循环获取别名map中的最后一个真实名称
缓存所有BD的元数据
Member member = element.getMember()
finishBeanFactoryInitialization
如果BeanDefinition中设置的是FactoryBean并且名称不以 &开头
获取所有要依赖于的bean进行遍历确定是否出现了dependsOn循环依赖存入缓存中并进行创建对应的依赖bean
(5)
processPropertySource(propertySource);
clearSingletonCache()
是否存在索引
检测是否需要配跳过(@Conditional)
当前bean名称与父bean名称不同,则递归获取父bean的父bean
如果当前容器获取不到beanName对应的实例对象就去父容器匹配
进行多个候选工厂方法的排名对比选出最小得分的方法,当得分先等时会存入一个list中(ambiguousFactoryMethods)
调用子类继承并实现了的onClose方法
进行excludeFiltersincludeFilters@conditional判断
如果包含bean就通过rbd来判
return c1
EarlySingletonObjects
如果以上判断都不通过,即无import相关的注解了就当成非import的普通配置类进行再次解析
factoryBean = this.beanFactory.getBean(factoryBeanName)->factoryClass = factoryBean.getClass();\t\t\tisStatic = false
return getBeanFactory();
默认情况下: 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
Set<BeanDefinitionHolder>doScan(String... basePackages)
判断被代理的接口中是否定义了equals()、hashCode()方法,如果程序员在接口中手动定义了这两个方法,则也会进行代理\t 否则这两个方法是不会走代理逻辑的
查看方法参数是否小于最小参数值,如果小于就直接跳过这个候选工厂否则就去查看getbean参数是否为空?不为空就判断个数是否等于方法个数如果·等于就直接去解析参数
GenericApplicationContextcloseBeanFactory->this.beanFactory.setSerializationId(null)
Object arg = beanFactoryfont color=\"#b71c1c\
@Bean对应的BeanDefinition
componentScanParser.parse()
首先先检测合并的BD中是否存在如果存在并且被创建过那么直接返回DB否则重新去合并DB-去检查当前的DB是否为抽象的
然后重新获取,去执行 不在已经执行过bean集合中并且实现了@Ordered注解的类
font color=\"#b71c1c\
scanner.doScan(StringUtils.toStringArray(basePackages));
true
DefaultAopProxyFactory.createAopProxy(AdvisedSupport config)
如果被代理对象没有实现接口,则判断被代理类是不是接口,或者被代理类是不是已经经过JDK动态代理之后的类从而获取想对应的接口
BeanFactoryUtils.transformedBeanName(name)
根据各个参数判断调用父容器的获取Bean方法
setCurrentInjectionPoint(previousInjectionPoint)
AnnotationConfigApplicationContext.close()
registerDefaultFilters()
用来获取方法入参名字的工具类
pbd = getMergedBeanDefinition(parentBeanName);
returnmbd.resolveBeanClass(beanClassLoader)
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition()
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null;->getApplicationEventMulticaster().multicastEvent(earlyEvent);
isFactoryBean(beanName)
// resolvableDependencies记录了某个类型对应某个Bean,启动Spring时会进行设置,比如BeanFactory.class对应BeanFactory实例\t\t\t// 注意:如果是Spring自己的byType,descriptor.getDependencyName()将返回空,只有是@Autowired才会方法属性名或方法参数名
将ImportRegistry注册为bean以支持ImportAware@Configuration类
解析依赖
如果ctors有值则需要进行构造方法注入,或者autowiredMode是AUTOWIRE_CONSTRUCTOR\t\t或者BeanDefinition中添加了构造方法的参数和值,或者调用getBean()方法时传入了args
赋值获取的缓存对象
String[] candidateNames = BeanFactoryUtils.font color=\"#b71c1c\
找注入点(所有被@Autowired注解了的Field或Method)
mbd.isFactoryBean = true
不符合成为组件条件
originalBeanName(name)
transformedBeanName(name)
Field field : getDeclaredFields(clazz)->fc.doWith(field);
先获取当前线程的classLoader
设置lifecycleProcessor,默认为DefaultLifecycleProcessor
SingletonFactory
解析scope注解
this.scanner.scan(basePackages);
其他scope(request,session)
初始化后
获取后置处理器的个数,并添加一个bean后置处理器
再次查看当前配置类是否存在父类,如果存在,不是java本身的类,并且没有被处理过就进行把它放入一个集合中
检测是否属于FactoryBean对象并进行处理
object = getCachedObjectForFactoryBean(beanName)
查看是否是单例的,是否需要进行销毁操作
实例话出来的是nullbean并且require为true就报错如果实例化出来的bean与类型不匹配就报错
检测自己添加的bean
factory.isSingleton() && containsSingleton(beanName)
GenericWebApplicationContext
如果当前的@lazy注解标识的注入点是接口就给代理类设置接口类型
trackedConditionEvaluator.shouldSkip(configClass)-> 跳过this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware->PropertyValues pvsToUse = bp.font color=\"#b71c1c\
获取bean工厂中自定义的监听器进行遍历设置
if->!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())
isStatic && isFrozen
return font color=\"#b71c1c\
获取缓存,如果存在对应的构造方法或参数然后确定是否需要对构造方法进行依赖注入(构造方法注入就像上面的@bean获取参数方式)如果需要就进行注入并返回实例化的bean,否则就使用默认的无参构造方法实例化并返回
type.isArray()
销毁单例池的bean
如果没有缓存将根据filed从BeanFactory中查到的匹配的Bean对象
Object sharedInstance = getSingleton(beanName)
设置scope的proxyMode实现
checkPropertySkipping(pvs)
实例化之后,属性设置之前
GenericTypeAwareAutowireCandidateResolver.isAutowireCandidate
registerBeanPostProcessors(beanFactory)
return new JdkDynamicAopProxy(config)
注册beanDefinition到beanDefinitionMap
prepareRefresh()
添加了事件监听器后,判断是否有earlyApplicationEvents,如果有就使用事件广播器发布earlyApplicationEvents\t\tearlyApplicationEvents表示在事件广播器还没生成好之前ApplicationContext所发布的事件
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);\t\t\t\t\t\t\tsbd.setSource(resource);
https://www.processon.com/view/link/5f97bc717d9c0806f291d7eb
componentType = resolvableType.getComponentType().resolve();
获取自定义赋值的属性
添加spring内部的bean后置处理器ApplicationListenerDetector负责把ApplicantsListener类型的Bean注册到ApplicationContext中
如果没有设置接口将使用cglib进行代理
this.earlyApplicationEvents = new LinkedHashSet<>()
如果还为空就匹配自己
解析过程
parser.parse(candidates); parser.validate();
否则就创建注册一个simple的事件发布器
只要存在@Component、@ComponentScan、@Import、@ImportResource@Bean 就是lite配置类
// 解析@Lazy、@Primary、@DependsOn、@Role、@Description注解,并设置对应值
beanFactory=obtainFreshBeanFactory()
为空要么是真的没有匹配的,要么是匹配的自己
destroyBeans()
getBean
是否存在注解属性
解析完成后赋值给RDB
如果被代理类本身就已经是Cglib所生成的代理类了就获取真正被代理的类与实现的接口
method.getParameterCount() == 0
判断是否需要转换并尝试使用类型转换器进行转换
public JdkDynamicAopProxy(AdvisedSupport config)
BService执行后续生命周期
(2)
match = font color=\"#b71c1c\
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null)
都没有就去创建BService
false创建对象
添加一个ResourceEditorRegistrar,注册一些级别的类型转化器-组成一个BeanPostProcessor,用来处理EnvironmentAware、EmbeddedValueResolverAware等回调
BeanUtils.getWriteMethodParameter(pd)boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered)
Modifier.isStatic(field.getModifiers()
进行进一步的筛选
方法是否存在@autowire、@value、@inject注解
Aspectj本身是通过编译期进行代理的,在Spring中就跟LoadTimeWeaver有关
pf.getProxy(dlbf.getBeanClassLoader())
getBean(beanName)
abd = new AnnotatedGenericBeanDefinition(beanClass)->shouldSkip(abd.getMetadata())
autowiredBeanName = font color=\"#b71c1c\
回调方法先过滤所有桥接方法即过滤与父类相同方法的重复注入点
多个线程同时来创建就要进行控制,保证单例
getBean(FACTORY_BEAN_PREFIX + beanName)
不是FactoryBean,就是普通Bean那么就直接查看类型关系
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces)
如果import的是DeferredImportSelector,表示推迟导入如果import的是普通的ImportSelector就继续处理所import进来的类
scannedBeanDefinitions = this.componentScanParser.font color=\"#b71c1c\
register(componentClasses);
if (!this.active) { activate(); }
refreshBeanFactory();
检测lookup-Methoid
遍历每个注入点进行依赖注入
for (String ppName : postProcessorNames)
(9)
根据pointcut过滤所有advisor是否符合当前类进行aop
else
publishEvent(new ContextRefreshedEvent(this));
如果单例池中存在bean就放入到缓存中
获取有销毁方法的bean
确保beanClass属性已经加载为Class对象
生成一个DB对象(确定对应的scope注解的创范围与是否存在ScopedProxyMode属性需要创建代理)并注册
注册一些spring环境相关的类与记录器
1.是否有继承DisposableBean或AutoCloseable接口2.beanDefinition.destroyMethodName设置为(inferred),那么将自动推断销毁方法(shutdown、close)3.是否有实现销毁的后置处理器并且每一个处理器是否存在销毁的方法
设置bean工厂使用context的类加载器-判断是否要忽略spel表达式的解析
如果类型为ByType或ByName先将自定义属性添加到propertyValueList集合MutablePropertyValues是PropertyValues具体的实现类
Set<BeanDefinition> findCandidateComponents(String basePackage)
如果当前不是factoryBean就直接返回
初始化前
如果前面都没返回最后会调用这个方法
主要方法根据给定的type寻找合适的name,参数3为true时会找到包括单例以外的bean
this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this);
去重处理,假如当前字段有两个注解标识,那么会存储先加载的,@resource快于@autowire
进行aop代理并生成对象
从工厂中获取messageSource,如果有就获取
else if (containsSingleton(beanName)) { return font color=\"#b71c1c\
获取所有的beanName执行后置单例初始化完成的方法
泛型或字段对应类型是否匹配
!isFactoryDereference->if (typeToMatch.isInstance(beanInstance)) { return true; }
查看需要的类型是不是接口,集合或者map
解析ImportResource注解,解析出一个全路径的Resources数组,然后进行占位符的填充,最后存入一个集合中
(6)
if (parameterCount >= minNrOfArgs)argsHolder = new ArgumentsHolder(explicitArgs)
boolean synthetic = (mbd != null && mbd.isSynthetic());-> object = font color=\"#f44336\
return object
ByName与ByType分离实现
跳过有自定义设置了注入的bean
从依赖map中获取当前销毁bean是否被谁所依赖循环销毁依赖者
会调用forName
for (BeanDefinition candidate : candidates)
mergedBeanDefinitions..stale = true->alreadyCreated.add(beanName)
BeanFactoryUtils.isFactoryDereference(name)->mbd.isFactoryBean = true->return beanInstance
Class<?> rootClass,proxySuperClass = this.advised.getTargetClass()
boolean multiple = indicatesMultipleBeans(requiredType)
如当前的bean是单例正在被创建,并且允许循环依赖那就提前缓存(三级缓存)单例创建工厂
ApplicationListenerDetector放在所有BeanPostProcessor之后,注意ApplicationListenerDetector的equals()方法实现
检查通过name所获得到的beanInstance的类型是否是requiredType必要是是用类型转换器转换类型(SimpleTypeConverter)
检测参数个数为0时打印日志
进行类中需要注入的field与method这里以@autowire与@value标记为例
finishBeanFactoryInitialization(beanFactory)
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName)
去单例池查找没有找到并且BService没有正在创建
如果是单例bean会注册以beanName为keyDisposableBean为value入disponsableBeans的map
模板方法,由子类实现非web的applicationcontext
// 使用的虚拟机是不是 GraalVM,默认都是jvm// 如果ProxyFactory的isOptimize(是否优化)为true, // 或者isProxyTargetClass为true, // 或者被代理对象没有实现接口, // 或者只实现了SpringProxy这个接口-> // 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理else -> // 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
onClose()
如果当前bean工厂有父bean工厂,并且messageSource是HierarchicalMessageSource而且能获取到父bean工厂的MessageSources就设置当前的MessageSources的父messageSource
传入beanclass创建BD对象,确定注册的类是否符合@condition注解
注意,在asConfigClass方法中,不仅会将candidate生成一个ConfigurationClass,还会记录一下candidate是被哪个类导入的importedBy
当前bean是否存在父bean
确定所有的key是不是合适的类型确定value是不是objectFactory类型,是的话调用getObject方法不是就确定是不是合适的类型
如果ctors有值则需要进行构造方法注入,或者autowiredMode是AUTOWIRE_CONSTRUCTOR\t\t或者BeanDefinition中添加了构造方法的参数和值,或者调用getBean()方法时传入了args\t构造方法注入:首先包括
当前beandefiniton是否实现factorybean
doRegisterBean
InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware->bp.font color=\"#b71c1c\
从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化《DefaultListableBeanFactory.java》
否则先通过beanname去找一次所有的bean(包括非单例)是否匹配不匹配就加&符号在进行二次匹配
检查是否出现了需要依赖的场景
this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses);
mbd.isSingleton()->instanceWrapper = this.factoryBeanInstanceCache.remove(beanName)
if (autowireNecessary)
BeanDefinition中添加了Supplier,相当于对象工厂则调用Supplier来得到对象(是否提供了生成bean的方法)
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
处理当前配置类上@bean注解的方法,并放入集合中然后再循环处理当前配置类实现的接口中的@bean方法,并放入集合中
if (isCandidateComponent(sbd))
此处的dependsOn循环依赖是出现在实例化阶段的,所以无法解决,将直接抛出遗产
String[] font color=\"#b71c1c\
(7)
SimpleAutowireCandidateResolver.isAutowireCandidate
查看field或者method参数是否存在@lazy注解
进行属性填充
初始化完成后判断当前的AService(正常原对象)和初始化完成后的对象是否相同(不同的原因可能是在初始化后新增了后置处理器然后生成原对象的代理类例如@Async)相同则从二级缓存中取出AService对象返回
如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了
OrderComparator.sort(candidates)->for (SourceClass candidate : candidates)
构造成一个stream,然后排序返回
mbd.getFactoryMethodName() != null->font color=\"#b71c1c\
先过滤自己注入自己的情况,然后判断@bean的autocandidate是不是为true
如果缓存中获取不到数据就去beanFactory中获取然后放入缓存中
如果当前在运行那么就原子性的设置关闭标志
result == null
proxySuperClass = rootClass.getSuperclass()additionalInterfaces = rootClass.getInterfaces()
if (isCandidateComponent(metadataReader))
返回一个代理类对象
处理ImportBeanDefinitionRegistrar
prepareBeanFactory(beanFactory);
是一个正常的bean就直接执行后置处理器
获取创建的bean包装类给BD设置对应的bean类型
f (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); }
记录一下propertyName对应的Bean被beanName给依赖了
清除所有缓存
将生成的对象放入二级缓存
ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary
是集合类型或者是接口
private Set<BeanDefinition>scanCandidateComponents(String basePackage)
initLifecycleProcessor()
如果获取到工厂方法只有一个并且参数为空就进行实例化并返回
refresh();
cglib代理类设置属性
bean.destroy()
有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)从缓存中拿出来并删除
DefaultListableBeanFactory.public Object font color=\"#b71c1c\
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
已上面的解析类解析出来的配置构建一个新增的配置类集合,然后出去已经加载过的
this.advised = config;\t\tthis.advisedDispatcher = new AdvisedDispatcher(this.advised)
判断是否有早创建的事件监听器如果有就先清空然后放入事件监听器的列表中最后清空earlyApplicationEvents
createAopProxy()
遍历所有的传入的扫描包路径
如果存在缓存则清理缓存解析注入点并缓存
进行注入
设置scope
1.对每个方法的参数进行遍历,先获取对应参数的类型于名称2.如果在mdb中指定了参数就‘匹配’获取对应下标位置的参数,如果参数为空就可能传参时没有按下标去传参,那么就按通用匹配去获取参数看哪个参数符合要求3.1 如果获取到了参数就去查看是否需要进行类型转换如果需要就进行转换,最后按下标记录在返回值中3.2 如果没有获取到参数就先查看是否允许Constructor自动注入(autowired设置的类型是否为construct),如果没有设置构造自动注入的属性就会报错,否则就按照参数注入(注入点)的方式去查找一个合适的参数(this.beanFactory.resolveDependency)
执行getObject方法返回对象
String superclass = sourceClass.getMetadata().getSuperClassName();-> this.font color=\"#e65100\
将被导入的类生成BeanDefinition(被导入的类也是一个bean~)并注册到Spring容器中\t\t\t@Component的内部类,@Import所导入的类都是被导入的类
span style=\"font-size: inherit;\
AbstractBeanFactory.registerDisposableBeanIfNecessary
存在,注解在注入时先生成一个代理对象注入给属性不存在,返回null
马上就要实例化Bean了,确保beanClass被加载了
遍历获取类上的@PropertySource注解并进行处理
postProcessBeanFactory(beanFactory)
如果名称以’&‘开头并且是FactoryBean就直接返回单例池的对象
验证Environment中是否存在对应的属性不存在会报错,可通过getEnvironment().setRequiredProperties()
使用AnnotatedBeanDefinitionReader去把新增的配置类加载为BD注册,然后把新增集合所有对象添加到已加载的集合中
执行lamba表达式返回代理对象或early对象如果是代理对象就设置earlyProxyReferences
从获取的beanname中遍历查看是否实现了PriorityOrdered如果实现了就添加到临时要执行的集合中(currentRegistryProcessors)与已经执行的集合中(processedBeans)最后遍历完成后对临时集合进行升序的排序并执行后置方法,然后清空临时集合
注册@Component对应的AnnotationTypeFilter
通过名称获取或创建单例对象解决循环依赖的过程
this.closed.set(false);\t\tthis.active.set(true);
转换名称解析为规范名称
AService
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
!mbd.postProcessed->font color=\"#b71c1c\
解析import注解
getResourcePatternResolver().getResources(packageSearchPath)for (Resource resource : resources)
false
getAutowireCandidateResolver().getSuggestedValue(descriptor)
for (AnnotationAttributes componentScan : componentScans)
mbdToUse.prepareMethodOverrides()
否则循环判断importCandidates
beanName = FACTORY_BEAN_PREFIX + beanName;->matchFound = font color=\"#b71c1c\
如果定义的scope是session、request这些,那么该Bean在注入给其他Bean时,得先生成一个代理对象注入给其他Bean 如果是这种情况,最终生成的BeanDefinition中的类是ScopedProxyFactoryBean,getObject()方法中会返回原本类的代理对象https://blog.csdn.net/qq_32077121/article/details/107805007?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
获取合并后的BeanDefinition
类似
candidates表示根据类型所找到的多个Bean,判断这些Bean中是否有一个是@Primary的
如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
ann = findAutowiredAnnotation(field)
return pvs
BService
扫描包
去二级缓存中找
factoryClass = mbd.getBeanClass();\t\t\tisStatic = true;
addDiscoverer(new StandardReflectionParameterNameDiscoverer());\t\taddDiscoverer(new LocalVariableTableParameterNameDiscoverer());
循环截取去除‘&’字符
#todo
不存在父bean
打印日志后进行下一个判断
new AnnotationConfigApplicationContext(Class<?>... componentClasses)
if (freshResolve
else使用默认的构造方法进行实例化
扫描
bdHolder.getBeanDefinition().isAutowireCandidate();
beanFactory.preInstantiateSingletons()->创建单例非懒加载的beanDefaultListableBeanFactory.preInstantiateSingletons()
根据beanName获取bean的内部类依赖然后遍历进行销毁
removeSingleton(beanName);this.disposableBeans.remove(beanName)->font color=\"#b71c1c\
找到type所匹配的所有bean
获取scope代理模式并设置给scanner,在扫描时除非有自定的scope注解,否则模式是这个模式
递归解析配置类,有可能通过解析一个配置类,得到了其他的配置类,比如扫描和Importt
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);\t\tbeanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);\t\tbeanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);\t\tbeanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);\t\tbeanFactory.ignoreDependencyInterface(MessageSourceAware.class);\t\tbeanFactory.ignoreDependencyInterface(ApplicationContextAware.class);\t\tbeanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
AnnotationBeanNameGenerator
beanFactory.setTempClassLoader(null);->beanFactory.freezeConfiguration();
如果包含beandefinition就通过mbd来判断
initPropertySources()
获取筛选后的对象
targetClass = advised.getTargetClass()->if (targetClass.isInterface()) { advised.setInterfaces(targetClass);}-> else if (Proxy.isProxyClass(targetClass)) { advised.setInterfaces(targetClass.getInterfaces());}-> specifiedInterfaces = advised.getProxiedInterfaces()
如果当前getbean不为只检测而需实际应用
mbd = new RootBeanDefinition(bd);
callbacks = mainCallbacks;return callbacks;
三级缓存创建可参考此处
AutowiredFieldElement.inject
检测循环导入,是就抛出异常
targetType != null && targetType != ClassUtils.getUserClass(beanInstance)->Class<?> classToMatch = typeToMatch.resolve()->classToMatch != null && !classToMatch.isInstance(beanInstance)
getLifecycleProcessor().onRefresh();
关闭此上下文本身的状态
否则去加载class对象
实例化非懒加载的单例Bean
mbd = new RootBeanDefinition(pbd);->合并属性 mbd.overrideFrom(bd);
如果一个属性对应的set方法在ignoredDependencyInterfaces接口中被定义了,则该属性不会进行自动注入(是Spring中的自动注入,不是@Autowired)
singletonsCurrentlyInCreation
查找所有符合条件的class并返回beandefinition集合
Object bean = font color=\"#f57f17\
实例化之后想要注入AService
mbd != null
field注入
按每个Bean的phase进行分组执行SmartLifecycle生命周期实现类的isAutoStartup和getPhase进行分组
if (containsBeanDefinition(bdName)) { return font color=\"#b71c1c\
String stereotype = extractStereotype(filter);
!mbd.isAbstract() && (allowEagerInit || (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) && !requiresEagerInitForType(mbd.getFactoryBeanName()))
获取已存在的合并bean
beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length())
Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); }
clearResourceCaches();
拿出所有的Lifecycle的Bean
如果dynamicLoader不为空就直接解析
CglibAopProxy.getProxy(ClassLoader classLoader)
AService执行后续生命周期
loadBeanDefinitionsForBeanMethod(beanMethod);
后置处理器执行属性注入例如 @autowired这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
ConfigurationClassPostProcessor.processConfigBeanDefinitions
循环@Bean生成BeanDefinition并注册
autowiringValue = AutowireUtilsfont color=\"#b71c1c\
!typeCheckOnly->markBeanAsCreated(beanName)
匹配获取spring.components中的include值,再判断类路径是否为basePackage
getEnvironment().validateRequiredProperties()
按分组执行start()
!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()
this.advised = config; // 设置JDK动态代理所要代理的接口 this.proxiedInterfaces = AopProxyUtils.font color=\"#b71c1c\
GenericApplicationContext
instanceWrapper == null->instanceWrapper = font color=\"#d32f2f\
如果没有@Autowired注解的构造方法,当前BeanDefinition的autowiremode也不是AUTOWIRE_CONSTRUCTOR,也没有指明所要用的构造方法参数值 则直接使用无参构造方法
之前是否有合并过?是否需要重新合并
发布容器关闭的事件只会其他扩展执行关闭操作
有多个候选工厂方法的话先获取mbd或getbean是否有传参并获取最小的参数个数,然后进行匹配
从缓存中获取,如果参数3为true表示从所有bean缓存获取否则只获取单例备案缓存
如果获取到了,但是个数不止一个就需要进一步匹配
publishEvent(new ContextClosedEvent(this))
phases.values().forEach(LifecycleGroup::start);
获取当前bean工厂里的所有DB名字循环判断是否时配置类,然后添加到集合通过@order注解进行升序排序
else if进行泛型处理类型不等于空,class名不以&开头然后去获取对应泛型,确定泛型与type的关系
hms.setParentMessageSource(getInternalParentMessageSource());
dynamicLoader.loadClass(className)
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer())
如果方法是静态的,那么将直接return
获取数组元素类型
mbd == null && containsBeanDefinition(beanName)
RootBeanDefinition mbd = null;\t\t\tRootBeanDefinition previous = null;
invokeBeanFactoryPostProcessors(beanFactory)
清除完后清除所有bean依赖的记录Map
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
targetInterceptor = (isStatic ? new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));}
(1)
遍历所有的BD然后执行此方法
canonicalName(BeanFactoryUtils.transformedBeanName(name))
!(beanInstance instanceof FactoryBean)->return beanInstance;
bean instanceof FactoryBean->(FactoryBean<?>) bean
如果是其他scope(session request等)
如果没有缓存则直接
// 被代理类,代理类的父类enhancer.setSuperclass(proxySuperClass); // 代理类额外要实现的接口 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
如果当前的bean工厂属于BeanDefinitionRegistry那么就遍历所有的bean工厂后置处理器(对于BeanDefinitionRegistryPostProcessor对象,会执行自己的postProcessBeanDefinitionRegistry()方法)然后如果是DB的可注册工厂后置处理器就执行并添加到registryProcessors否则就添加到regularPostProcessors中
获取类型后去寻找合适的bean然后后续转换类型与排序
containedBeanMap.remove(beanName)->destroySingleton(containedBeanName)
如果没有找到自定义的MessageSource就创建一个默认的
registerListeners
是否有成为组件的条件;不是接口,抽象类或存在lookup注解
如果从FactoryBean缓存中获取不到对象则执行getObject()方法,返回的object不可能为null(会返回NullBean)
如果mdb是是单例的那么就去获取或者创建单例对象然后再去检查FactoryBean
如果解析出来是clas就返回是String就直接转换然后标志置为true
当前Bean中能进行自动注入的属性名
doClose();
解析配置类并将BeanDefinitionHolder首先封装为ConfigurationClass然后解析是否存在@condition注解并进行判断,如果被多个类导入就把相同的bean合并在这个过程中会进行扫描、导入等步骤,从而会找到其他的ConfigurationClass
value = beanFactory.font color=\"#b71c1c\
检查spring容器中是否存在相相同名字的bean
反射给filed赋值
解析并缓存注入点信息
什么样的属性能进行自动注入?1.该属性有对应的set方法2.没有在ignoredDependencyTypes中 3.如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中4.属性类型不是简单类型,比如int、Integer、int[]
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces()
获取beanName生成器与环境类并创建*配置类解析器*
创建FactoryBean对象
Object result = getAutowireCandidateResolver().font color=\"#b71c1c\
创建一个根据类型从bean工厂获取扫描出来的DB工厂后置处理器集合并扫描
ProxyFactory.getProxy(@Nullable ClassLoader classLoader)
后置处理合并后的BeanDefinition
如果import的类实现了ImportBeanDefinitionRegistrar接口就实例化对象并添加到集合中
实例化后创建lamba表达式并以beanName为key表达式以value放入三级缓存
https://www.processon.com/view/link/6146def57d9c08198c58bb26
this.containedBeanMap.clear();\t\tthis.dependentBeanMap.clear();\t\tthis.dependenciesForBeanMap.clear();
enhanceConfigurationClasses(beanFactory);
Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType;}
单例池中没有name对应的Bean对象,就只能根据BeanDefinition来判断出类型了
获取和被代理类所匹配的Advisor
如果确定了构造方法判断是否需要注入
设置将scope信息设置到beanDefinition
String[] parentResult =font color=\"#b71c1c\
result.isEmpty()
匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字
与MessageSources的实现一致获取的是themeSource
do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName;}} while (resolvedName != null);
smartSingleton.afterSingletonsInstantiated()
将Field或Method记录到BeanDefinition中的externallyManagedConfigMembers中,表示该Field或Method是BeanFactory外部管理的
String className = mbd.getBeanClassName()Object evaluated = font color=\"#f57f17\
如果Bean工厂存在自定义的applicationEventMulticaster事件处理器就获取
MutablePropertyValues newPvs = new MutablePropertyValues(pvs)
清除依赖map中的set value为bean的'我依赖'
根据数组元素类型找到所匹配的所有Bean
当前获取的beandefinition不是无抽象属性,是单例的,不是懒加载
super(config)
如果scope是原型扩展处理实例化前实例化扩展实例化后FactoryBean处理
sharedInstance != null && args == null
this.componentsIndex != null && indexSupportsIncludeFilters()
resolvedBeanNames = font color=\"#b71c1c\
获取当前的注入模式
进行实例化
this()
getCustomTypeConverter()
获取所有的beandefinitions并遍历
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());-> configClasses.removeAll(alreadyParsed);
上层条件满足,拿到descriptor所对应的属性上的所有注解,检查是否有@Qualifier,如果有,看是否和当前bdHolder匹配
AutowiredMethodElement.inject
获取代理对象所实现的接口
argsToUse = mbd.resolvedConstructorArguments->argsToResolve = mbd.preparedConstructorArguments;argsToUse = font color=\"#b71c1c\
(8)
所需要的类型是Optional
遍历targetClass中的所有Field
result = DefaultListableBeanFactory.font color=\"#b71c1c\
ConstructorResolver.instantiateUsingFactoryMethod
主要正常逻辑在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
将配置类解析BD并注册到bean工厂
for (SourceClass candidate : importCandidates)
cl = ClassLoader.getSystemClassLoader()
resolveEmbeddedValue((String) value)
AbstractBeanFactory.BeanPostProcessorCache
ClassLoader beanClassLoader = getBeanClassLoader();\t\tClassLoader dynamicLoader = beanClassLoader;\t\tboolean freshResolve = false;
处理条件@qualifier注解
initApplicationEventMulticaster
isLazy(descriptor)
String bdName = BeanFactoryUtils.transformedBeanName(beanName)
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) -> return font color=\"#b71c1c\
符合成为组件条件加入set集合中
BeanFactoryPostProcessors按入场方式分为: 1. 程序员调用ApplicationContext的API手动添加 2. Spring自己扫描出来的 * BeanFactoryPostProcessor按类型又可以分为: 1. 普通BeanFactoryPostProcessor 2. BeanDefinitionRegistryPostProcessor 执行顺序顺序如下: 1. 执行手动添加的BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry()方法 2. 执行扫描出来的BeanDefinitionRegistryPostProcessor(实现了PriorityOrdered)的postProcessBeanDefinitionRegistry()方法 3. 执行扫描出来的BeanDefinitionRegistryPostProcessor(实现了Ordered) 的postProcessBeanDefinitionRegistry()方法4. 执行扫描出来的BeanDefinitionRegistryPostProcessor(普通) 的postProcessBeanDefinitionRegistry()方法 5. 执行扫描出来的BeanDefinitionRegistryPostProcessor(所有) 的postProcessBeanFactory()方法6. 执行手动添加的BeanFactoryPostProcessor 的postProcessBeanFactory()方法 7. 执行扫描出来的BeanFactoryPostProcessor(实现了PriorityOrdered) 的postProcessBeanFactory()方法 8. 执行扫描出来的BeanFactoryPostProcessor(实现了Ordered) 的postProcessBeanFactory()方法 9. 执行扫描出来的BeanFactoryPostProcessor(普通) 的postProcessBeanFactory()方法 ConfigurationClassPostProcessor就会在第2步执行,会进行扫描
如果没有缓存那么注册依赖bean关系检测参数个数与解析的个数是否相同判断是否已经实例化对应的bean并且类型是否匹配
类似步骤
创建Bean实例
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
循环遍历所有includefilter中导入的名称for (TypeFilter filter : this.includeFilters)
scopeMetadataResolver.resolveScopeMetadata(abd)->processCommonDefinitionAnnotations(abd)->for (Class<? extends Annotation> qualifier : qualifiers)
循环依赖过程与解决
注册beanclass类型 : 对应的对象在依赖注入寻找bean时会使用到findAutowireCandidates
autowiredBeanNames.add(autowiredBeanName);->instanceCandidate = descriptor.font color=\"#b71c1c\
this.messageSource = beanFactory.getBean(font color=\"#fbc02d\
处理nonOrderedPostProcessorNames会判断是否是MergedBeanDefinitionPostProcessor类型如果是就单独存放在一个集合中
一级缓存是否存在,二级缓存是否存在,三级缓存是否存在对应的lamba表达式,有则运行生存bean然后把bean存入二级缓存中并删除三级缓存的表达式如果未出现循环依赖的那么这里二级缓存三级缓存都不会存在值
!mbd.isPrototype() && font color=\"#b71c1c\
一般都为true
object = alreadyThere
for (InjectedElement element : elementsToIterate)->font color=\"#b71c1c\
addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext)) ignoreDependencyInterface(ServletContextAware.class);
遍历每个方法参数,找到匹配的bean对象
dependencies = this.dependentBeanMap.remove(beanName)->destroySingleton(dependentBeanName)
instanceCandidate = matchingBeans.get(autowiredBeanName)
Predicate<String> selectorFilter = selector.getExclusionFilter();\t\t\t\t\t\tif (selectorFilter != null) {\t\t\t\t\t\t\texclusionFilter = exclusionFilter.or(selectorFilter);\t\t\t\t\t\t}
如果存在后置处理器就循环并调用这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值\t\t\t\tAutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
筛选后为空,并且不为集合接口或者require为true就返回一个错误
bd instanceof RootBeanDefinition
for (String basePackage : basePackages)
cl == null->cl = ClassUtils.class.getClassLoader()
实例化前回调如果执行完成后返回了一个值就直接return
初始化返回的beanWrapper
给beanDefinition配置默认值
不排除或者被包含
onRefresh
在解析一个配置类时,如果类上有@Component,则会判断内部类是不是lite配置类并进行解析,并且会记录为被导入的
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)
initMessageSource();
添加三个Spring内置接口:SpringProxy、Advised、DecoratingProxyisInterfaceProxied 接口是否实现对应的类
beanFactory.preInstantiateSingletons()
super()
如果当前的bean不是辅助功能的bean则执行后置处理器
类似此逻辑
for循环获取并移除里面的bean然后执行销毁
获取所有的BeanPostProcessor名称
packageSearchPath= classpath*:com/zhouyu/**/*.class
web环境
准备BeanFactory 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象 3. 记录ignoreDependencyInterface 4. 记录ResolvableDependency 5. 添加三个单例Bean
ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) && !memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())->candidates.add(memberClass);
configCandidates = new ArrayList<>();-> String[] candidateNames = registry.getBeanDefinitionNames();->ConfigurationClassUtils.font color=\"#b71c1c\
遍历所有的field然后执行回调方法
Set<BeanDefinition> candidates.add(sbd)
设置标志
AnnotationConfigApplicationContext
bean不为空,实现了beanFactoryBean并且bean名称格式不为&xx就调用getObjectType方法并判断当前获取的bean是否实现了对应type类型
生成beanName
BeanDefinition中添加了Supplier,则调用Supplier来得到对象
factoryMethodToUse = mbd.getResolvedFactoryMethod()->
如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
一般不使用
数组类型
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric()->matchingBeans = font color=\"#b71c1c\
循环依赖处理
componentScan.getAnnotationArray()->basePackages = new LinkedHashSet<>();basePackagesArray = componentScan.getStringArray(\"basePackages\
matchingBeans.size() > 1
matchFound = font color=\"#b71c1c\
非静态工厂,获取对应的工厂类获取工厂类的class并设置静态标记为false
这里会解析类中需要注入的field与method@autowire、@value、@inject
返回注入点实例对象
else获取名称与对应的对象
StringUtils.toStringArray(this.disposableBeans.keySet())->destroySingleton(disposableBeanNames[i]);
Object shortcut = descriptor.resolveShortcut(this);
mbd.resolvedConstructorOrFactoryMethod != null->resolved = true autowireNecessary = mbd.constructorArgumentsResolved
metadata = font color=\"#b71c1c\
获取当前的beanDefinition个数
如果之前发生循环导入就报错否则就将当前类加入importStack,处理当前内部类
如果当前存在于beanDefinitionMap中
先调用父类构造方法创建bean工厂然后无参构造方法创建扫描器与bd读取器(可创建BD)
获取对应的写方法(setxx)并确定是否继承了PriorityOrdered接口如果继承了那么将不允许立即初始化需要进行后置处理器进行处理
根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置getBeanFactory().registerResolvableDependency()
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton( AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);->this.environment->parser = new ConfigurationClassParser->candidates = new LinkedHashSet<>(configCandidates); ->alreadyParsed = new HashSet<>(configCandidates.size());
加载非懒加载的beanfactorybean.getObject()
设置当前bean处于创建的状态
finishRefresh
synchronized (getSingletonMutex())
遍历所有的BeanDefinitions查找非别名的类名获取合并bd
查看实现的注入方法并进行注入
取优先级最高的Bean@priority
获取所有spring自己的监听器,遍历设置到处理器中
后续
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey)->metadata = buildAutowiringMetadata(clazz);
如果是非web的applicationcontext那么重复刷新会报错,否则重新哦设置序列号id
如果获取的beanName不为空就去解析它是否为spel表达式并执行有可能执行完成后会直接返回一个class对象
Class<?> dependencyType = descriptor.getDependencyType();-> if (dependencyType.isInterface()) { pf.addInterface(dependencyType); }
文字描述
判断当前创建的bean是否是Factorybean如果是则进行以下步骤并进行转换
所需要的的类型是ObjectFactory,或ObjectProvider
mbd == null || mbd.stale
Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);-> return (type != null && typeToMatch.isAssignableFrom(type))
this.factoryBeanObjectCache.get(beanName)!=null
记录匹配过的beanName有可能筛选出来的是某个bean的类型,此处就进行实例化如果value是class类型就实例化
String candidateName = entry.getKey();\t\t\tObject beanInstance = entry.getValue();
boolean reiterate = true; while (reiterate) { reiterate = false;->if (!processedBeans.contains(ppName))reiterate = true;
getApplicationEventMulticaster().addApplicationListener(listener);
bd.getParentName() == null
mbd.hasBeanClass()->this.beanClass instanceof Class
new ClassPathBeanDefinitionScanner()
静态工厂,回去对应的工厂类并设置静态标记为true
!isConfigurationFrozen() || type == null || !allowEagerInit->return font color=\"#b71c1c\
AutowiredAnnotationBeanPostProcessor.postProcessProperties
for (String beanName : beanNames) ->singletonInstance instanceof SmartInitializingSingleton
存在父bean
处理@ImportResource导入的xml解析
descriptor instanceof StreamDependencyDescriptor
以name构造缓存对象(考虑原型bean)
invokefont color=\"#b71c1c\
this.scanner = new ClassPathBeanDefinitionScanner(this);
父类构造方法初始化
当前Bean中能进行自动注入的属性名并循环遍历每一个属性名获取属性对应的属性描述器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
如果beanClass被加载了就直接返回(属性的beanClass对象是否为class而不是String对象)
if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(SCOPE_SINGLETON); }
Thread.currentThread().getContextClassLoader()
遍历targetClass中的所有Method
Object exposedObject = bean;->font color=\"#b71c1c\
Modifier.isStatic(method.getModifiers())
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
先获取所有方法并遍历执行回调方法
注册后置销毁方法
线程中类加载器为null的情况下,获取加载ClassUtils类的类加载器
!NativeDetector.inNativeImage() &&\t\t\t\t(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))
DelegatingMessageSource dms = new DelegatingMessageSource();\t\t\tdms.setParentMessageSource(getInternalParentMessageSource());
boolean exposeProxy = this.advised.isExposeProxy(); boolean isFrozen = this.advised.isFrozen(); boolean isStatic = this.advised.getTargetSource().isStatic();
默认为DefaultAopProxyFactory
查找父容器的合适beanName然后合并beanName集合返回
(3)
.getProxy(classLoader)
执行生命周期处理器的关闭方法
while (!candidates.isEmpty());
if (!beanDefinition.isExternallyManagedConfigMember(member)) {\t\t\t\tbeanDefinition.registerExternallyManagedConfigMember(member);\t\t\t\tcheckedElements.add(element);\t\t\t}
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName)
getAopProxyFactory().createAopProxy(this)
否则就去解析mdb的参数并构建参数列表
是否需要注入类以java开头将不注入
遍历每个属性名,并去获取Bean对象,并设置到pvs中
提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪个构造方法
if (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
解析${} 环境变量获取
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); }-> return new ObjenesisCglibAopProxy(config);
!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
InjectedElement element : this.injectedElements
nonOrderedPostProcessors.add(pp);->internalPostProcessors.add(pp);
getBeanFactory().destroySingletons()->super.destroySingletons()
includeFilters.add(new AnnotationTypeFilter(Component.class))
startBeans(boolean autoStartupOnly=true)
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames)
earlyProxyReferences
确定使用什么技术代理对象
遍历完当前类的field与method后将注入点存在集合的开始位置(如果父类存在注入点那么先执行父类注入)查看是否存在父类并查找注入点
如果存在value注解就进行解析
标记AService正在被创建
metadata.checkConfigMembers(beanDefinition)
checkConfigurationClassCandidate中获取className时如果是@bean的配置类就会拿不到,直接放回,不在解析@Bean类
else如果当前容器中不存在就在父容器中查找对应的bean
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory->TargetSource ts = new TargetSource()->ProxyFactory pf = new ProxyFactory();-> pf.setTargetSource(ts)
Collection.class.isAssignableFrom(type) && type.isInterface()
验证现在BeanDefinition是否已经推断出了构造方法或工厂方法
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource)
需要被排除
将内部是lite配置类并且名称不与当前类名相同
解析key与value的类型,判断key是不是String类型不是就返回空,然后使用value的类型去寻找合适的bean
int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
先注册nonOrdered再对Merged升序排序后注册
registerBeanDefinitionForImportedConfigurationClass(configClass);
如果不为空就设置默认的占位符解析器
类似这里的逻辑
return result
synthetic为true,表示这个Bean不是正常的一个Bean,可能只是起到辅助作用的,所以这种Bean就不用去执行PostProcessor了
先获取类型转换器如果类型不一致时会查看是否定义了对应的转换器并进行转换注入
this.deferredImportSelectorHandler.process()
scan()
去除特殊bena名称factorybean(&xx)
获取类型(setxx(xx x))判断创建需要注入属性的依赖描述器(是字段注入还是方法参数注入等)根据类型找到的结果
resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null->mbdToUse = new RootBeanDefinition(mbd);\t\t\tmbdToUse.setBeanClass(resolvedClass);
如果配置了 `factory-method` 工厂方法,则调用该方法来创建一个实例对象 通过 @Bean 标注的方法会通过这里进行创建找到最匹配的 Method 工厂方法,获取相关参数(依赖注入),然后通过调用该方法返回一个实例对象(反射机制)
执行bean的销毁方法
getDefaultClassLoader()
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
模板方法调用子类这里调用的是GenericWebApplicationContext创建Enviroment并判断是否是web程序,如果是就设置servlet的配置内容
调用完processConfigBeanDefinitions后执行此方法增强full配置类(proxyBeanMethods = true)被生成代理对象设置到BD中
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate)
遍历所有resource获取matadataReader(asm)
判断工厂类是不是存在是静态工厂还是非静态的
遍历所有的bean后置处理器,然后分类成PriorityOrdered、Ordered、nonOrderedPostProcessorNames
尝试获取优先的构造方法所有的显示编写的构造方法
if (this.earlyApplicationListeners != null) { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } this.active.set(false);
this.importStack.contains(configClass)-> elsethis.importStack.push(configClass);font color=\"#b71c1c\
遍历所有的beandefinition进行处理
exposedObject = font color=\"#b71c1c\
ScopedProxyMode scopedProxyMode = componentScan.getEnum(\"scopedProxy\");->scopedProxyMode != ScopedProxyMode.DEFAULT-> elseClass<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass(\"scopeResolver\");\t\t\tscanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
如果还是获取不到方法就进行异常处理,仅是无法获取就抛出之前有拦截到的错误如果有多个评分相等并且是最低分的也会抛出错误最后对当前解析的工厂方法与参数进行缓存并返回实例化对象
提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪个构造方法,查看哪个构造方法有@autowire注解
0 条评论
下一页