1、 AnnotationConfigApplicationContext功能
該類可以實現基於Java的配置類加載自定義在Spring的應用上下文的bean。
1.1 使用方式一:在構造方法中完成注冊和刷新
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MessageConfiguration.class); System.out.println(ctx.getBean("beanName"));)//根據bean的名字獲得與之對應的實例。 public AnnotationConfigApplicationContext(Class... annotatedClasses) { this(); this.register(annotatedClasses); this.refresh(); }
1.2 使用方式二:掃描包路徑下所有的配置類,最后刷新
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("org.spring.springboot"); ctx.refresh(); 可以直接以包名作為參數傳入。 public AnnotationConfigApplicationContext(String... basePackages) { this(); this.scan(basePackages); this.refresh(); }
使用方式三:通過使用register方法具體到注冊哪個配置類,最后刷新。
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh();
2、 分析AnnotationConfigApplicationContext
AnnotationConfigApplicationContext繼承了GenericApplicationContext並實現了接口AnnotationConfigRegistry
2.1 接口:AnnotationConfigRegistry注冊方法和掃描方法。注解配置注冊表。用於注解配置應用上下文的通用接口,
擁有一個注冊配置類和掃描配置類的方法。
2.2 GenericApplicationContext通用應用上下文。
GenericApplicationContext 繼承 AbstractApplicationContext 實現 BeanDefinitionRegistry,內部持有一個
DefaultListableBeanFactory實例,這個類實現了BeanDefinitionRegistry接口,可以在它身上使用任意的bean definition讀取器。
2.2.1 AbstractApplicationContext
ApplicationContext接口的抽象實現,沒有強制規定配置的存儲類型,僅僅實現了通用的上下文功能。
這個實現用到了模板方法設計模式,需要具體的子類來實現其抽象方法。自動通過registerBeanPostProcessors()
方法注冊BeanFactoryPostProcessor, BeanPostProcessor和ApplicationListener的實例用來探測bean factory里的特殊bean。
2.2.2 BeanDefinitionRegistry
用於持有像RootBeanDefinition和 ChildBeanDefinition實例的bean definitions的注冊表接口。GenericApplicationContext
類中的實例DefaultListableBeanFactory實現了這個接口,它對這個接口的實現實際上是通過調用這個實例的相應方法實現的,
因此可以通過相應的方法向beanFactory里面注冊bean。
源碼:
public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException; void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String var1); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String var1); }
2.3 構造方法
AnnotatedBeanDefinitionReader——BeanDefinition解析器用來解析帶注解的bean
2.3.1 AnnotatedBeanDefinitionReader的構造器
注解的條件判斷器ConditionEvaluator
該方法在初始化的時調用,當配置的類上有@Conditional注解並且返回false的時候,容器就不處理該類
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
這個是關鍵,注冊AnnotationConfigProcessor
// 默認使用三個bean處理器 public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { registerAnnotationConfigProcessors(registry, (Object)null); } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8); RootBeanDefinition def; if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) { def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) { def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor")); } if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) { def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor")); }
2.3.1.1 @Bean的分析
是在refresh的invokeBeanFactoryPostProcessors(beanFactory)階段,核心方法是loadBeanDefinitionsForBeanMethod,該方法處理了各種各樣的注解。
注解分析的關鍵方法loadBeanDefinitionsForBeanMethod
該方法具體實現對包括如下注解的處理。
autowire
initMethod
destroyMethod
是在refresh的invokeBeanFactoryPostProcessors(beanFactory)階段,核心方法是loadBeanDefinitionsForBeanMethod,
該方法處理了各種各樣的注解。
2.3.1.2 ConditionEvaluator:配置的類上有@Conditional注解並且返回false的時候,容器就不處理該類
2.3.1.3 @Autowired 重點關注AutowiredAnnotationBeanPostProcessor后置處理器。
2.3.1.4 當AutowiredAnnotationBeanPostProcessor 作為接口MergedBeanDefinitionPostProcessor的實現時
AutowiredAnnotationBeanPostProcessor后置處理器的方法調用棧postProcessMergedBeanDefinition
該方法是在AbstractAutowireCapableBeanFactory.java的doCreateBean中調用的。該方法是創建bean實例的核心方法:
- 1)創建Bean的實例:createBeanInstance(beanName, mbd, args)
- 在此后:applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
- 調用AutowiredAnnotationBeanPostProcessor的方法postProcessMergedBeanDefinition
- 2)populateBean;給bean的各種屬性賦值
- 3)initializeBean:初始化bean;
2.3.2 ClassPathBeanDefinitionScanner——bean的掃描器 用來掃描類
注冊解析傳入的配置類(使用類配置的方式進行解析)
調用容器的refresh方法初始化容器