javascript
Spring5源码 - 00 IOC容器创建_前期准备
文章目錄
- 實例化容器
- 源碼分析
- this
- 調用父類的構造函數
- 然后調用自己的構造函數
- new AnnotatedBeanDefinitionReader(this);
- new ClassPathBeanDefinitionScanner(this);
- register(annotatedClasses);
實例化容器
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);源碼分析
進去看一下
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {//調用構造函數this();//注冊我們的配置類register(annotatedClasses);//IOC容器刷新接口refresh();}這里我們分析一下AnnotationConfigApplicationContext 構造函數中的前兩個方法
- this()
- register(annotatedClasses);
this
調用父類的構造函數
調用AnnotationConfigApplicationContext無參的構造器,會先調用父類GenericApplicationContext的無參構造器
public GenericApplicationContext() {//創建IOC容器 ,用于存放beanthis.beanFactory = new DefaultListableBeanFactory();}調用父類的構造方法 生成一個IOC容器,主要是存放bean定義
然后調用自己的構造函數
public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");/*** 初始化注解模式下的bean定義掃描器 * 調用AnnotatedBeanDefinitionReader構造方法,傳入的是this(AnnotationConfigApplicationContext)對象*/this.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();/*** 初始化我們的classPath類型的bean定義掃描器*/this.scanner = new ClassPathBeanDefinitionScanner(this);}我們看下這里面主要的方法
new AnnotatedBeanDefinitionReader(this);
跟進去
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}就是為bean定義讀取器賦值,
那毫無疑問 先getOrCreateEnvironment(registry) ---- 創建環境
/*** Get the Environment from the given registry if possible, otherwise return a new* StandardEnvironment.*/private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");if (registry instanceof EnvironmentCapable) {return ((EnvironmentCapable) registry).getEnvironment();}return new StandardEnvironment();}然后繼續this方法的調用 ,
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;this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}第一步
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);創建一個條件計算器對象 ,用于處理 條件表達式計算 @Conditionl注解
第二步 , 為容器中注冊系統的bean定義信息 ,這些后置處理器 是Spring開天辟地初始化內部beandefinition的地方, 沒有這個,就沒有IOC,非常重要。
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);來跟進去
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {//注冊了實現Order接口的排序器beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}//設置@AutoWired的候選的解析器if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);/*** 為我們容器中注冊了解析我們配置類的后置處理器ConfigurationClassPostProcessor* 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor*/if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 為我們容器中注冊了處理@Autowired 注解的處理器AutowiredAnnotationBeanPostProcessor* 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor*/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));}/*** 為我們容器中注冊處理@Required屬性的注解處理器RequiredAnnotationBeanPostProcessor* 名字叫:org.springframework.context.annotation.internalRequiredAnnotationProcessor*/if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}/*** 為我們容器注冊處理JSR規范的注解處理器CommonAnnotationBeanPostProcessor* org.springframework.context.annotation.internalCommonAnnotationProcessor*/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));}/*** 處理jpa注解的處理器org.springframework.orm.jpa.support.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));}/*** 注冊事件監聽器工廠*/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;}new ClassPathBeanDefinitionScanner(this);
簡言之 初始化我們的classPath類型的bean定義掃描器
/*** ClassPathBeanDefinitionScanner就是用來掃描我們classpath下的標注了@Service @Compent @Respository @Controller* 注解* @param environment 環境對象* definition profile metadata* @param resourceLoader the {@link ResourceLoader} to use* @since 4.3.6*/public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;/*** 設置默認的掃描規則為true的話 默認是掃描所有的 若使用 includeFilters 來表示只包含需要設置為false*/if (useDefaultFilters) {registerDefaultFilters();}//設置環境對象setEnvironment(environment);//設置資源加載器setResourceLoader(resourceLoader);}我們來關注下 registerDefaultFilters();
/*** 這也是為啥我們標注了@Compent @Repository @Service @Controller 能夠被識別解析* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and* JSR-330's {@link javax.inject.Named} annotations, if available.**/@SuppressWarnings("unchecked")protected void registerDefaultFilters() {//加入掃描我們的@Component的this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {//加入掃描我們的JSR250規范的this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.debug("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 {//加入掃描我們JSR330規范的this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}支持分析完了this(),接下來看看 register(annotatedClasses);
register(annotatedClasses);
看名字,也能猜到 是注冊我們的配置類的方法。
其實
public void register(Class<?>... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");this.reader.register(annotatedClasses);}繼續 register
public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);}}可以看到是支持多個配置類的,
public void registerBean(Class<?> annotatedClass) {doRegisterBean(annotatedClass, null, null, null);}我們發現Spring真正干活的方法都是do開頭的。。。。。,所以重點關注
繼續
/*** Register a bean from the given bean class, deriving its metadata from* class-declared annotations.* * @since 5.0*/<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(instanceSupplier);ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);}// 注冊自己傳入的主配置類bean定義到容器中BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}重點就是最后幾句 : 注冊自己傳入的主配置類bean定義到容器中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);其實這個register 就是使用 AnnotatedBeanDefinitionReader實例化的過程中
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}生成的bean定義讀取器注冊配置類
到此為止,refresh方法之前的兩個方法就是這樣的 ,get了么…
總結
以上是生活随笔為你收集整理的Spring5源码 - 00 IOC容器创建_前期准备的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5源码 - 05 invok
- 下一篇: Spring MVC源码 - 00开篇主