springIOC源码分析
2020-05-18 13:57:35 0 举报
springIOC源码分析
作者其他创作
大纲/内容
注入到容器中
6: 注入我们bean的后置处理器(对注册的bean后置处理器的实例化) registerBeanPostProcessors(beanFactory);
scanCandidateComponents(String basePackage)
将配置类的bean定义信息注册到容器中,放到beanFactory的beanDefinitionNames中 ...
创建一个bean定义集合,并将结果返回Set<BeanDefinition> candidates
this()构造方法
对每个配置类循环解析
invokeBeanFactoryPostProcessors(beanFactory);
1:注册@Import的bean定义registerBeanDefinitionForImportedConfigurationClass(configClass);2:@bean导入进来的组件loadBeanDefinitionsForBeanMethod(beanMethod);3:@ImportResources导入进来的\t\tloadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); 4:ImportBeanDefinition注解导入进来的\t\tloadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
3:没有注册过,则创建bean定义信息并注册到容器中,并放到Set<BeanDefinitionHolder> beanDefs bean定义持有器中返回
2:获取告诉子类初始化Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +\t\t\t\t\tresolveBasePackage(basePackage) + '/' + this.resourcePattern
调用父类GenericApplicationContext构造函数,创建beanFactory
循环处理我们包扫描出来的bean定义
此时不会注册bean定义到容器中,而是将含有@bean的方法添加到configClass
设置默认的扫描规则为true的话 默认是扫描所有的
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
处理 @Import 注解
将我们的beanFactory强制转化为BeanDefinitionRegistry
processConfigurationClass(ConfigurationClass configClass)
excludeFilters
8:初始化注册事件多播器 initApplicationEventMulticaster();
new AnnotatedBeanDefinitionReader(this);
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath)
processConfigBeanDefinitions(registry)
this.refresh()
注册我们的配置类到容器(beanFactory)中
为啥使用DefaultListableBeanFactory?因为通过看beanFactory接口的继承结构时,发现这个是功能最全的。
getBean(\"&\"+beanName)
3.2.1 设置权限definition.setRole(2);
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
我们的配置类上解析处ComponentScans的对象集合,把我们扫描出来的类变为bean定义的集合
创建一个常规的bean工厂后置器和BeanDefinitionRegistryPostProcessor类型
真正的解析
循环遍历配置类,依次注册
初始化applicationEventMulticaster 应用多播器组件this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory)
bean的后置处理器的个数 beanFactory.getBeanPostProcessorCount()成品的个数 直接保存在beanPostProcessors集合中的postProcessorNames.length beanFactory工厂中beand定义的个数 +1 在后面又马上注册了BeanPostProcessorChecker的后置处理器
注册除了@CompentScan的bean定义信息
1:准备刷新上下文环境prepareRefresh()
没有需要被解析的,跳出循环
递归调用,可能是想着在@Controller上会有@CompentScan
处理我们的@propertySource注解的
把我们的配置包装成ConfigurationClass
遍历candidates,并将bean定义信息注册到容器中
创建一个配置类解析器对象new ConfigurationClassParser()
processCommonDefinitionAnnotations(abd)
创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度
实例化剩下的单实例bean
10:把我们的事件监听器注册到多播器上 registerListeners();
parser.validate()
9:这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomat的. onRefresh();
2:检查各个组件的是否注册过了registry.containsBeanDefinition(String beanName)
4:留个子类去实现该接口postProcessBeanFactory(beanFactory);
retrieveBeanMethodMetadata(sourceClass)
3:对bean工厂进行填充属性prepareBeanFactory(beanFactory);
循环遍历basePackages
this.register(MainConfig.class...);括号中的配置类可以是多个
如果是我们要加载的,则包装成ScannedGenericBeanDefinition,并放到candidates
调用自己实现的BeanFactoryPostProcessor
new ClassPathBeanDefinitionScanner(this)
初始化我们的classPath类型的bean定义扫描器,注册默认的过滤器,包含@Compent的注解的类
includeFilters
是
BeanDefinitionRegistryPostProcessors实现了Ordered接口的(什么都没做)
设置bean定义的属性信息1:是否懒加载 lazy2:@DependsOn:定义Bean初始化及销毁时的顺序:3:是否标识了@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。。。。。
loadBeanDefinitions(configClasses)
发布的事件也是在这里执行的
真正解析我们的bean定义信息
scanner.doScan(StringUtils.toStringArray(basePackages))
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
检查bean定义是否合法beanDefinition.validate()
getBean(beanName)
循环遍历
findCandidateComponents(basePackage)
创建bean定义读取器,主要是扫描出内部的组件的bean定义信息注册到我们的容器中,在beanFactory.beanDefinitionMap属性中。
否
冻结所有的bean定义,不让修改了beanFactory.freezeConfiguration();
bean定义注册到容器中registerAnnotationConfigProcessors(this.registry)
if (useDefaultFilters) { registerDefaultFilters(); }设置为false
调用自己实现的BeanDefinitionRegistryPostProcessor
解析我们的配置类,可能是一个循环的过程,对sourceClass
5: 调用我们自定义的bean工厂的后置处理器和框架的解析配置类的后置处理器,解析我们的配置类,包括@compentScan @Import @Bean等,将我们自己定义的bean的bean定义信息注册到容器中
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
注册的内部后置处理器和其他的组件1:解析@Configuration配置bean定义后置处理器ConfigurationClassPostProcessor2:处理@Autowired 注解的bean后置处理器AutowiredAnnotationBeanPostProcessor3:处理@Required属性的注解处理器RequiredAnnotationBeanPostProcessor4:处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor5:处理jpa注解的处理器PersistenceAnnotationBeanPostProcessor6:处理监听方法的注解解析器EventListenerMethodProcessor7:注册事件监听器工厂DefaultEventListenerFactory
beanFactory = new DefaultListableBeanFactory();
basePackages
是否是工厂bean
registerBean(annotatedClass)
获取BeanPostProcessor类的bean定义信息
遍历容器中的bean定义信息,找到我们的配置类,并将他们放到configCandidates中,若我们的配置类上有@Order,则根据数值将configCandidates集合中的配置信息排序
将主配置类的信息解析映射到这个类
lazyInit
spring容器的启动AnnotationConfigApplicationContext(MainConfig.class)
@Compent @Repository @Service @Controller 能够被识别解析 1:this.includeFilters.add(new AnnotationTypeFilter(Component.class));2:加入扫描我们的JSR250规范的javax.annotation.ManagedBean3:加入扫描我们JSR330规范的javax.inject.Named
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
处理 类接口的
这些后置处理器注意只有ConfigurationClassPostProcessor实现的是BeanDefinitionRegistryPostProcessor接口,是bean工厂的后置处理器,执行时机是bean定义完成之后,实例化之前
parser.parse(candidates);
此时不会注册bean定义到容器中下
processPropertySource(propertySource)
scanner = new ClassPathBeanDefinitionScanner
检查是否是单例的,且不是Abstract和不是懒加载的!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
从容器中找到BeanDefinitionRegistryPostProcessor这种类型的后置处理器
beanFactory.preInstantiateSingletons();
将资源路径下的类转为Resource
如果有方法重写(需要代理)又是factory bean(无法代理)那就抛出异常
处理 方法上的@Bean 注解
遍历获取所有的bean定义信息 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
11:实例化我们剩余的单实例bean. finishBeanFactoryInitialization(beanFactory);
定义一个集合才存放我们的配置类
找到候选的bean定义信息
3.1:创建bean定义信息RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source);
注册配置类bean定义doRegisterBean
12:最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的) finishRefresh();
创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
7: 初始化国际化资源处理器. initMessageSource();
scope有扩充了RequestScope和@SessionScope,里面是对原有的Scope进行扩展,request和session的域和默认的代理模式TARGET_CLASS(uses CGLIB),non-singleton scoped instance
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
1:获取beanFactoryDefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
1:获取在没有初始化多播器的早期事件,并发布2:将我们定义的事件注册到多播器上
new AnnotatedGenericBeanDefinition(annotatedClass)
将componentScan封装成ClassPathBeanDefinitionScanner,并将各个属性设置进去
把我们的包路径转为资源路径
register(Class<?>... annotatedClasses)
定义一个currentRegistryProcessors,保存当前准备创建的BeanDefinitionRegistryPostProcessor实例

收藏
0 条评论
下一页