Spring初始化、IOC
2022-04-27 15:21:37 0 举报
Spring 初始化启动源码流程图
作者其他创作
大纲/内容
根据Bean定义中的Scope类型执行
单例池中存在
object = getCachedObjectForFactoryBean(beanName)
执行生产Bean逻辑
添加到Bean定义集合中返回
生成非懒加载的单例Bean
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName())
// 递归获取最上层parentBeanNameString parentBeanName = transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {pbd = getMergedBeanDefinition(parentBeanName);}
把BeanClass改为真正的Class
执行Spring自带的依赖注入执行
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
如果入参getBean入参前缀带&则直接返回beanInstance
在mergedBeanDefinitionsMap中添加未使用Parent属性的Bean定义
Object sharedInstance = getSingleton(beanName)
GenericApplicationContext()
markBeanAsCreated(beanName)
注册Bean
判断是否实现了SmartInitializingSingleton如果实现了则调用其实现方法
注册Bean的依赖信息
判断BeanName是否已经注册到beanDefinitionMap中
isCandidateComponent(sbd)
判断单例Bean是否被标记 正在创建,并加入正在创建的标记
如果Bean定义中指定了InitMethodName 初始化方法
ApplicationContext context=new AnnotationConfigApplicationContext(MainStart.class)
解析Scope注解元数据,并设置到Bean定义中
更改Bean定义中的stale标记 标记为准备实例化创建
afterPrototypeCreation(beanName)
调用FactoryBean的getObject
BeanFactoryUtils.isFactoryDereference(name)
throw new BeanCurrentlyInCreationException(beanName)
createBean()
通过类加载器去加载Bean的Class
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
通过ASM技术把资源解析为元数据
循环进行解析
internalCommonAnnotationProcessor;CommonAnnotationBeanPostProcessor;
if (mbd.hasBeanClass())
Set<BeanDefinition> candidates = findCandidateComponents(basePackage)
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate)
register(componentClasses)
以下两个用于事件处理
// 创建Bean定义集合Set<BeanDefinition> candidates = new LinkedHashSet<>()// 匹配获取当前包下的所有class文件地址解析包路径String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
获取FactoryBean的真正实例Bean
初始化Bean定义的读取器
Spring自带的注入方式执行完后这里会调用到AutowiredAnnotationBeanPostProcessor处理@Autowired等注入的注解
判断注解中是否有value属性,有则使用
mbd.constructorArgumentsResolved
scanCandidateComponents(basePackage)
标记正在创建原型Bean
真正处理Spring依赖注入逻辑
刷新容器,实现IOC整个生命周期
判断是否为抽象 && 单例 && 非懒加载的Bean定义
new DefaultListableBeanFactory()
创建Bean
没有配置value,则通通过类名获生成BeanName
单例池中没有,可能是原型(多例)或者还未创建
移除标记
初始化的方法回调
DefaultListableBeanFactory.registerBeanDefinition()
创建Bean实例
如果原型Bean正则被准备创建,抛出异常
获取实现FactoryBean的类实例
beanFactory.preInstantiateSingletons()
mbd.isPrototype()
获取原始的beanName 有&则去除 没有则返回原始,有别名则也返回的是最原始的
从合并后的Bean定义容易中获取
internalAutowiredAnnotationProcessor;AutowiredAnnotationBeanPostProcessor;
InstantiationAwareBeanPostProcessor#postProcessProperties
调用构造方法
registerBean(componentClass)
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
循环把所有读取到的包路径扫描成Bean定义,此时获取到的Bean定义只有BeanClass
mbd = new RootBeanDefinition(bd)
通过类加载器去加载Bean
int resolvedAutowireMode = mbd.getResolvedAutowireMode()
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit())
// 获取默认请求下的类加载器, 如果通过context.getBeanFactory().setBeanClassLiader(..);// 或在Tomcat中通过 Thread.currentThread().setContextClassLoader(..)设置类加载器// 可指定使用类加载器,默认AppClassLoader
判断单例池中是否有实例对象
生成一个继承ParentBean属性的Bean定义如果本身设置了属性则优先使用自己的
判断BeanClass是否是Class是则直接返回
通过Read和Scan之后 注册Bean定义
根据Request请求创建Bean
// 某个Bean被哪些Bean依赖了dependentBeanMap// 某个Bean依赖了哪些BeandependenciesForBeanMap
不存在,则把Bean定义放入Map中
如果配置了,spring会自带的依赖植入方法,会直接调用实例化Bean中的set方法去执行。@Bean(autowire = Autowire.BY_NAME)根据setXXX的方法名称去Spring中找对应的Bean进行注入。@Bean(autowire = Autowire.BY_TYPE)根据set方法的入参去找对应的Bean进行注入
实例化后,可调用合并后的Bean定义PostProcessors
初始化最BeanFactory最顶层实现功能是最全的并且实现了注册Bean定义的功能
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
BeanPostProcessor#postProcessAfterInitialization
设置了Parent属性
finishBeanFactoryInitialization(beanFactory)
初始化后PostProcessor
解析Lazy、Primary、DependsOn、Role、Description注解并设置到Bean定义中
此处可通过Bean定义的后置处理,直接对Bean属性进行添加mbd.getPropertyValues().addPropertyValues()是否注入由注入的后置处理逻辑实现
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
这个类会解析加了@Configuration的配置类,还会解析@ComponentScan、@Component等注解扫描等包。主要用来解析Bean
启动类
ClassLoader beanClassLoader = getBeanClassLoader();dynamicLoader.loadClass(className);
scope.get
internalPersistenceAnnotationProcessor
Bean对象都生产完成后调用实现Bean生命周期的回调
根据参数推断构造方法去实例化
String[] dependsOn = mbd.getDependsOn()
初始化Bean定义的扫描器核心方法为doScan()后续在Spring启动过程中会调用
true
BeanPostProcessor#postProcessBeforeInitialization
调用其指定的初始化方法
doScan(basePackages)
从单例池中获取实例
if (sharedInstance != null && args == null)
beforeSingletonCreation(beanName)
new AnnotatedBeanDefinitionReader(this)
为Bean定义设置一些默认值
实例化后的PostProcessors
object = factory.getObject()
false去生产Bean
添加创建标记
生产所依赖的Bean
用于解析@Autowired及@Value等注解
candidates.add(sbd)
beforePrototypeCreation(beanName)
BeanNameAware#setBeanName
解析BeanName
// 在单例池中获取对象Object singletonInstance = getSingleton(beanName)
this()
创建真正的Bean对象(getObject()返回的对象)
String nameToLookup = originalBeanName(name);parentBeanFactory.getBean(nameToLookup);
调用子类构造方法前会先调用构造方法
判断是否实现了SmartFactoryBean,如果实现了该方法且实现方法isEagerInit返回true,则立即去生产Bean
把Bean定义放到map中并把beanName维护到集合
isPrototypeCurrentlyInCreation(beanName)
把依赖信息注册到两个Map中
isCandidateComponent(metadataReader)
afterSingletonCreation(beanName)
determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition)
把创建好的Bean放入单例池中
internalEventListenerFactory;DefaultEventListenerFactory;
AUTOWIRE_BY_TYPE
internalConfigurationAnnotationProcessor;ConfigurationClassPostProcessor;
AnnotationBeanNameGenerator.generateBeanName()
for (String beanName : beanNames)循环容器启动时扫描到的所有BeanName
判断扫描出来的类 是否为顶层类 或静态类, 即 非内部类判断是否为接口 或 抽象类如果是抽象类 且 有方法使用了@Lookup 则返回true
注册Spring核心的一些初始化类的Bean定义
判断该Bean定义中是否设置了Parent属性
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName)
实例化前的BeanPostProcessors,如果有值,则直接返回方法返回的对象
AUTOWIRE_BY_NAME
获取Bean实例,如果是FactoryBean则获取的是其getObject返回
String beanName = transformedBeanName(name)
如果配置了componentsIndex优先根据文件扫描,提高效率
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName)
if (isFactoryBean(beanName))
解析Spring表达式。一般不会使用。如果使用类表达式可能返回一个Class,如果没有使用返回的还是BeanClassName
mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);
new ClassPathBeanDefinitionScanner(this)
初始化逻辑
通过类加载器加载Bean
refresh()
mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass)
// 生产Bean对象本身,(而非调用FactoryBean)Object bean = getBean(FACTORY_BEAN_PREFIX + beanName)
填充Bean
创建方法上带@Bean的实例
把实现FactoryBean的真正实例Bean(getObject())放入缓存实例Map中
Bean初始化
getBean(beanName)
mbd.isSingleton()
循环所有的BeanPostProcessor,找出对应的,并执行方法postProcessBeforeInstantiation
判断解析后的元数据是否被其他注解排除?是否添加了注册Bean的注解?例:@Component判断该类是否为一个条件类?即添加了@Conditional,如果添加了则调用matches方法判断是否符合生产Bean的条件
smartSingleton.afterSingletonsInstantiated()
singletonObject = singletonFactory.getObject()
从父BeanFactory中去生产Bean
移除创建标记
初始化前PostProcessor
for (Resource resource : resources)
setBeanClassName(this.metadata.getClassName());setResource(metadataReader.getResource());
getBean(dep)
BeanClass先设置类的名称, 等Bean初始化创建后 再赋值对应的Class,原因是此时类还没被加载初始化
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource)
第一次赋值为字符串,类的路径名
获取@DependsOn(加载Bean时需要依赖的Bean) 注解value
BeanFactory parentBeanFactory = getParentBeanFactory();parentBeanFactory != null && !containsBeanDefinition(beanName)
获取合并后的Bean定义,如果未使用Parent属性,则还是原来的
进行一些Aware的回调
internalEventListenerProcessor;EventListenerMethodProcessor;
getBean时入参没有加&且 beanInstance 实现了FactoryBean
BeanFactoryAware#setBeanFactory
this.reader.register(componentClasses)
判断是否实现了FactoryBean
Bean定义Map中不包含该Bean && 存在父BeanFactory走此逻辑
判断是否存在@DependsOn循环依赖,存在则抛异常
InitializingBean#afterPropertiesSet
从缓存集合中获取,第一次获取为null
把合并后的Bean定义存到何必后到Bean定义Map中
删除单例Bean创建标记
BeanClassLoaderAware#setBeanClassLoader
收藏
0 条评论
回复 删除
下一页