Spring IOC创建流程
2024-01-22 21:47:41 2 举报
登录查看完整内容
SpringIOCbean完整创建流程
作者其他创作
大纲/内容
获取异步器Executor executor = getTaskExecutor();
MessageSourceAware
register(componentClasses);
创建容器时先初始化父类GenericApplicationContext创建beanfactory
创建bean实例时,选择使用类的那个构造方法进行实例化
14
BeanFactoryPostProcessor
扫描标注有@Autowired 、 @Value的子段。对这些字段进行属性赋值
BeanClassLoaderAware
2
注册bean的后置处理器到beanPostProcessors中
registerListeners();
获取beanFactory中所有继承自BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的beanFactory的后置处理器,按照继承PriorityOrdered、继承Ordered、普通beanfactory进行排序,依次调用beanfactoryPostprocesser的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法
最后容器刷新 发布刷新事件
19
设置basePackageClasses扫描的类,会加载该类包路径下的所有组件
获取所有继承ApplicationListener接口的监听器名称放入applicationListenerBeans中,这里并没有进行真正的监听器注册只是记录了一个bean的名称
initMessageSource();
如果是一个FactoryBean,从容器中获取bean时,将获取到FactoryBean中getObject()方法生成的特殊bean。如果要正常获取bean,需要在获取bean时指定&+beanName。mybatis就是使用factoryBean在getObject()方法中为接口类创建的jdk动态代理
发布容器关闭事件publishEvent(new ContextClosedEvent(this));
第八次调用BeanPostProcessorAbstractAutoProxyCreator ibp;
22
spring发送事件默认是同步的,可以通过往多播器中设置异步器异步发布事件setTaskExecutor(@Nullable Executor taskExecutor)
3
17
postProcessBeanFactory
获取配置类上componentScan注解的属性,如: basePackages、basePackageClasses、lazyInit 、excludeFilters、includeFilters
1
1.解析@propertySource注解
7
设置scanner
递归出口if (sourceClass.getMetadata().hasSuperClass());如果配置类还有父类,再进行递归,如果没有父类表示配置类解析完成,退出递归return null;
解析导入的spring的xml配置,放入importedResources中
标记该bean正在创建,解决循环依赖时会用到singletonsCurrentlyInCreation.add(beanName)
this.beanFactory = new DefaultListableBeanFactory();
继承延时DeferredImportSelector,放入deferredImportSelectors,不做处理,springboot的自动装配会用到这个bean定义
设置容器active状态this.active.set(false);
6
CommonAnnotationBeanPostProcessor
递归
registerBeanPostProcessors(beanFactory);
finishRefresh()
5
2.解析@ComponentScan注解
setBeanFactory(AbstractAutowireCapableBeanFactory.this);
设置resourcePattern属性中的扫描正则表达式,默认**.*.Class
第七次调用BeanPostProcessorInstantiationAwareBeanPostProcessor ibp;
4
postProcessAfterInitialization()
2.注册创建IOC容器的基础beanDefinition
设置nameGenerator属性中的beanName生成策略,默认为类名首字母小写.
。。。
准备beanFactory 工厂,设置bean的类加载器,bean的表达式解析器(#{“”})忽略一些bean的自动装配,注册默认bean,添加一个事件监听相关的bean的后置处理器
解析标注有@Bean的方法,放入beanMethods中
第九次调用BeanPostProcessorDestructionAwareBeanPostProcessor ibp;
将标在方法上标注有@EventListener注解的类注册进多播器
判断bean是否继承FactoryBean,如果是FactoryBean使用&+beanName创建bean实例
找到符合条件组件后创建为一个bean定义:ScannedGenericBeanDefinition
invokeBeanFactoryPostProcessors(beanFactory);
implement null
DefaultEventListenerFactory
InstantiationAwareBeanPostProcessor第一次调用BeanPostProcessor
通过实现对应的Aware接口方法拿到容器上下文中的信息。如: environment、applicationContext
internalConfigurationAnnotationProcessor
扫描 @PostCustruct @PreDestroy @Resource注解
13
国际化时使用
InitDestroyAnnotationBeanPostProcessor
设置includeFilters属性中的包扫描包括策略
事件监听器工厂
EventListenerMethodProcessor
实例化ImportBeanDefinitionRegistrar,放入importBeanDefinitionRegistrars中
这个方法是在创建容器前进行一系列的初始化操作,设置容器激活,设置关闭为false 添加一些早期事件等。
这里说明一下componentScans解析流程,其他方式都很简单
postProcessBeforeInitialization()
ConfigurationClassUtils 类 第125 - 134 行
implement Ordered
finishRefresh();
@Resource @value @Autowired 注解的进行属性赋值
9
EnvironmentAware
internalAutowiredAnnotationProcessor
prepareRefresh();
调用上面注册到容器的多播器的multicastEvent()方法发布事件
AnnotationConfigApplicationContext(Class<?>... componentClasses)
20
setBeanName(beanName);
synchronized (this.startupShutdownMonitor)同步器保证refresh()线程安全
初始化调用,如果bean实现了InitializingBean接口,会调用该方法进行bean的自定义初始化
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);找到所有候选组件
preInstantiateSingletons()创建单例bean循环所有bean定义的名字List<String> beanNames依次创建bean
3.解析配置类,注册为bean定义,spring中重要的一个调用。
循环引用时调用,为bean创建动态代理
postProcessBeanFactory(beanFactory);
invokeInitMethods()
prepareBeanFactory(beanFactory);
再调用isCandidateComponent的另一个重载方法进行过滤。过滤条件:不是接口,不是抽象方法等,spring集成mybatis会重写这个方法,让接口也加入到候选组件中后面进行jdk动态代理
registerListeners()
解析@componentScan配置路径下的所有bean,并注册到beanDefinitionMap中
finishBeanFactoryInitialization(beanFactory);
IOC创建顺序
isCandidateComponent(metadataReader)执行排除和包括过滤策略
注册监听器
implement PriorityOrdered
第五次调用BeanPostProcessorInstantiationAwareBeanPostProcessor ibp;
设置lazyInit属性中的懒加载策略
afterPropertiesSet()
空方法,扩展使用。
发布容器启动完成的事件publishEvent(new ContextRefreshedEvent(this));
BeanDefinitionRegistryPostProcessor
bdp.postProcessMergedBeanDefinition()
EmbeddedValueResolverAware
onRefresh();
关闭容器
循环解析上一步生成的bean定义set集合scannedBeanDefinitions,判断解析出来的是否是一个配置类,如果是进行递归解析。
不是延时,调用selectImports()返回类的全限定名,递归解析成普通的bean定义processImports()
设置basePackages包扫描路径
this()
将经过上面两层过滤的候选组件放入candidates返回
ibp.getEarlyBeanReference();
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
beanFactory.addBeanPostProcessor(postProcessor);
List<> BeanPostProcessors
internalEventListenerFactory
beanName
getSingleton(beanName);首先从一级缓存中获取 bean,如果获取不到再进行创建bean,这个方法里面还有解决循环依赖的逻辑
initializeBean(); 初始化
ApplicationContext.close()
设置excludeFilters属性中的包扫描排除策略
postProcessBeanDefinitionRegistry()
普通类配置类都当做配置类进行递归解析processConfigurationClass,放入imports中
21
定义扫描器ClassPathBeanDefinitionScanner scanner,componentScan中的包路径使用这个扫描器进行扫描
BeanNameAware
当前bean继承BeanFactoryAware,实现setBeanFactory()方法,可以拿到容器上下文中的beanFactory工厂
RootBeanDefinition
internalEventListenerProcessor
18
this.scanner = new ClassPathBeanDefinitionScanner(this);
导入的类继承ImportSelector
setBeanClassLoader(bcl);
ibp.postProcessAfterInstantiation();
springframework-5.2.16.RELEASE
4.解析@ImportResource注解
关闭beanfactorycloseBeanFactory();
getBean(beanName);获取bean
ApplicationEventPublisherAware
createBean()开始创建bean
16
String beanName = transformedBeanName(name);得到bean的真实名字,如果bean有别名将在这里进行转换
发布早期事件getApplicationEventMulticaster().multicastEvent(earlyEvent);
11
ibp.postProcessBeforeDestruction()
ConfigurationClassPostProcessor
invokeAwareMethods()
创建一个注解读取器,其中注册了很多创建IOC容器的基础beanDefinition类
List<> registryProcessors
invokeCustomInitMethod()
将@compoentScan中配置的包路径下的所有可成为bean的类解析成bean定义
AutowiredAnnotationBeanPostProcessor
创建一个配置解析类,用来解析candidates中的配置ConfigurationClassParser parser;parser.parse(candidates);
将判断出的所有配置类放入candidates 的set 容器中
scanner.doScan(StringUtils.toStringArray(basePackages));开始包路径扫描
空实现,对bean的扩展,可以自定义bean的后置处理器截断属性赋值,或者做其他属性赋值前的操作
BeanFactoryAware
第六次调用BeanPostProcessorInstantiationAwareBeanPostProcessor ibp;
为bean创建动态代理。如该bean标注了 @Transactional事务注解或者该bean是一个切面,都会在这里进行动态代理的创建
当前bean继承BeanClassLoaderAware,实现setBeanClassLoader()方法,可以拿到当前bean的类加载器
ibp.postProcessProperties();
ApplicationContextAwareProcessor
ResourceLoaderAware
initApplicationEventMulticaster();
创建一个包扫描器,这里的scanner 是交给用户调用,Spring 容器本身不用
beanFactory.registerSingleton()向beanfactory中注册一个beanName为applicationEventMulticaster的事件多播器
空实现
processPropertySource(propertySource);解析配置类上的@propertySource注解将配置文件解析成PropertySource放在全局的propertySources中
循环postProcessorNames,调用getBean获取bean实例,根据继承PriorityOrdered、Ordered、普通bean,按照这个顺序进行判序最后依次注册到beanPostProcessors中
12
第四次调用BeanPostProcessorSmartInstantiationAwareBeanPostProcessor ibp;
创建bean,spring中的一个很重要调用
第三次调用BeanPostProcessorMergedBeanDefinitionPostProcessor bdp;
8
通过反射或者工厂创建bean实例
继承DisposableBean接口的bean销毁前调用 destroy()((DisposableBean) this.bean).destroy();
this.reader.loadBeanDefinitions(configClasses);,上面的步骤中并没有将@Bean和@Import标注的注册到beanDefinitionMap中,而是在这一步统一进行beanDefinition注册
第二次调用BeanPostProcessorSmartInstantiationAwareBeanPostProcessor ibp;
internalCommonAnnotationProcessor
3.解析@Import注解
从多播器中删除监听器执行标准有 @PreDestroy注解的方法等
10.bean
5.解析@Bean注解
导入的是普通类或普通配置类
解析配置类:传入容器的配置类,解析标注有@Import、@Component、@ImportResource、@ComponentScan或者类的内部方法上标注有@Bean的配置类并生成beanDefinition
初始化前 调用加了@PostConstruct注解的方法
this.reader = new AnnotatedBeanDefinitionReader(this);
15
ibp.determineCandidateConstructors()
InitializingBean
判断当前类是否是配置类,并且配置类上是否添加有@Configuration注解,如果有在当前类的beanDefinition属性上设置CONFIGURATION_CLASS_ATTRIBUTE = “full”如果没有标注@Configuration注解设置CONFIGURATION_CLASS_ATTRIBUTE = “lite\"”
componentClasses 是传入ApplicationContext的配置类,这个方法会将该配置类解析成一个beanDefinition 并且注册到beanDefinitionMap中。在后续会被ConfigurationClassPostProcessor解析,从中读取出一系列的beanDefinition注册到beanDefinitionMap中。
refresh()
10
创建事件多播器
设置scopedProxy属性中的代理生成策略,默认no 为jdk动态代理。还有两个值分别是:interfaces(jdk) 、targetClass(cjlib)
populateBean(); 属性赋值
导入的类继承ImportBeanDefinitionRegistrar
0 条评论
回复 删除
下一页