Spring启动过程源码分析(1)——AnnotationConfigApplicationContext之初始化Scanner和Reader
2021/11/19 20:12:29
本文主要是介绍Spring启动过程源码分析(1)——AnnotationConfigApplicationContext之初始化Scanner和Reader,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Spring启动过程源码分析(1)
——AnnotationConfigApplicationContext之初始化Scanner和Reader
我们以AnnotationConfigApplicationContext为起点来探究Spring的启动过程
首先引入眼帘的就是AnnotationConfigApplicationContext的构造方法,而我们今天只来探讨this();
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { //this()方法这里就创建了一个Bean工厂和Reader和Scanner this(); register(componentClasses); refresh(); }
public AnnotationConfigApplicationContext() { StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create"); // 生成并注册5个BeanDefinition // 1.ConfigurationClassPostProcessor // 2.AutowiredAnnotationBeanPostProcessor // 3.CommonAnnotationBeanPostProcessor // 4.EventListenerMethodProcessor // 5.DefaultEventListenerFactory this.reader = new AnnotatedBeanDefinitionReader(this); createAnnotatedBeanDefReader.end(); // 注册默认的includeFilter this.scanner = new ClassPathBeanDefinitionScanner(this); }
AnnotationConfigApplicationContext首先会生成Reader和Scanner,但在这之前,BeanFactory其实已经实例化完成了
因为AnnotationConfigApplicationContext是GenericApplicationContext的子类,父类的构造器要优先于子类构造器执行,所以在执行AnnotationConfigApplicationContext类的无参构造时,会先执行GenericApplicationContext的无参构造:
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
一、AnnotatedBeanDefinitionReader
Spring在实例化AnnotatedBeanDefinitionReader做了很多,最主要的就是将内部的后置处理器注册到Spring中
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; //ConditionEvaluator对象封装了spring容器的信息 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); /** * 将所有相关的后置处理器注册到这个registry中 */ AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
将spring相关信息记录到conditionEvaluator对象后,spring开始注册相关后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) { //将刚刚开始第一次new得bean工厂获得, DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { //加载组件,其中包括AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver //AnnotationAwareOrderComparator可以对实现PriorityOrdered、Ordered以及被@Order注解修饰的类进行统一的排序 if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } //AutowireCandidateResolver 用来判断一个给定的 bean 是否可以注入,最主要的方法是 isAutowireCandidate if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } //BeanDefinitionHolder中有beanDefinition,beanName,alias Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); //null /** * registerPostProcessor方法: * 将beanName和BeanDefinition按Key—value键值对得方式放在BeanDefinitionMap中 * 将BeanName放在BeanDefinitionNames列表中, * 将BeanName和BeanDefinition封装在BeanDefinitionHolder中, * 将封装好得BeanDefinitionHolder放在BeanDefs列表中。 * 这里其实就是注册内部的后置处理器 */ beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } //AutowiredAnnotationBeanPostProcessor if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader())); }catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } //EventListenerMethodProcessor if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } //DefaultEventListenerFactory if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
二、ClassPathBeanDefinitionScanner
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { //添加includeFilters //注册一个@Component注解对应的Filter registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
在开篇的时候我们提到了Scanner的用法,其中就提及到了includeFilters
DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(factory); //得到该包下类的个数 // int scan = classPathBeanDefinitionScanner.scan("com.beans"); // System.out.println(scan);//6 //扫描没有加@Componment注解的类,并注册到容器中,未通过注解或其他方式定义Bean的类也不会添加到容器中 //classPathBeanDefinitionScanner.addExcludeFilter(new AnnotationTypeFilter(Component.class)); //扫描加了@Componment注解的类,并注册到容器中 classPathBeanDefinitionScanner.addIncludeFilter(new AnnotationTypeFilter(Component.class)); //获取bean Object bean = factory.getBean(BeanTest.class); System.out.println(bean);//com.beans.BeanTest@5ccddd20
Spring会默认向includeFilters添加了@Componment注解
protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); }catch (ClassNotFoundException ex) { // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. } try { this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); }catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
到这里Spring就完成了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner注解的实例化
这篇关于Spring启动过程源码分析(1)——AnnotationConfigApplicationContext之初始化Scanner和Reader的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27消息中间件底层原理资料详解
- 2024-11-27RocketMQ底层原理资料详解:新手入门教程
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器