入口代碼:
public class SpringAnnotationStarter {
public static void main(String[] args) {
//建立一個新的AnnotationConfigApplicationContext,從給定的元件類派生bean定義并自動重新整理上下文。
new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);
}
}
複制代碼
在上面的測試中,使用的AnnotationConfigApplicationContext來重新整理上下文,傳入參數是我們定義的配置類。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
複制代碼
點進去可以發現,首先是調用空參構造器,然後是注冊配置類,最後重新整理,是以從這三個步驟進行梳理
1. this()
這就是一個空參構造器。
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
複制代碼
從代碼可以看出,是給reader和scanner兩個屬性進行指派。
reader的類型是AnnotatedBeanDefinitionReader ,點進去看源碼,這是個擴充卡,也就是adapter,用于bean類的程式設計注冊,解析帶有注解的bean的beanDefinition。在reader的指派如下:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
複制代碼
傳入目前類,并且根據目前環境調用重載的構造進行上下文建立,getOrCreateEnvironment看名字大概就是沒有建立,有就擷取,這就不看了,直接去關注重載的構造器
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);
}
複制代碼
這裡ConditionEvaluator點進去是為context指派,根據上下文建立一個ConditionContextImpl。
關鍵在于AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
AnnotationConfigUtils是一個Spring内部工具類,用于識别注解配置類中的bean定義,registerAnnotationConfigProcessors是為在給定的系統資料庫中注冊所有後置處理器,也就是PostProcessor。包括一些核心注解,形如:if(!registry.containsBeanDefinition(XXXXXXXXXXXXX))
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//從上下文拿到beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//解析注解ConfigurationClassPostProcessor ,友善後續注冊BeanDefinition
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 ,友善後續注冊BeanDefinition
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));
}
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;
}
複制代碼
最後将BeanDefinition集合傳回。到這裡reader就初始化完成了
然後scanner類型是為給定的bean工廠建立一個新的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) {
registerDefaultFilters();//注冊@Component的預設Filters
}
setEnvironment(environment);//設定要在解析占位符和評估@Conditional注釋元件類時使用的環境。
setResourceLoader(resourceLoader);//将ResourceLoader設定為用于資源位置。這通常是一個ResourcePatternResolver實作。
}
複制代碼
從這裡可以得出,主要用于掃描注解的設定。
2. register(componentClasses);
在上一步中,通過reader和scanner分别對BeanFactory以及核心的注解,過濾器,環境等進行了配置。
register方法中,傳入的是我們寫的配置類。
跟進,發現調用的是reader的register方法。
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
複制代碼
繼續跟進:
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
複制代碼
周遊所有傳入的componentClasses,對Bean進行注冊,再跟進,我們會進入真正的注冊邏輯doRegisterBean
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
複制代碼
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//聲明BeanDefinition,下面都是填充屬性
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//設定用于建立bean執行個體的回調(可能為null)
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//作用域
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//處理abd中的通用注解,@Lazy、@Primary、@DependsOn、@Role以及@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//下面這段關于qualifiers判斷是否有限定注解@Primary@Lazy
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));
}
}
}
//處理回調
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//将abd封裝成BeanDefinitionHolder,然後對BeanDefinition注冊
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//向BeanFactory進行注冊
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
複制代碼
到這裡相當于把我們寫的配置注冊到Spring了。
3. refresh();
這個方法,點進去就是一個refresh方法,對應Spring的初始化中的refresh,org.springframework.context.support.AbstractApplicationContext#refresh,對應着Spring生命周期 下面這段是之前學Spring的時候在網上找的,大緻流程如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 準備此上下文以進行重新整理、設定其啟動日期和活動标志以及執行任何屬性源的初始化。
prepareRefresh();//重新整理前的預處理
// 建立初始化BeanFactory,這個過程中loadBeanDefinitions()方法,輸入beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
// 1.設定BeanFactory的類加載器為ApplicationContex的類加載器
// 2.設定beanFacory的語言表達式處理器
try {
this.postProcessBeanFactory(beanFactory);
// 執行BeanFactoryPostProcessor的方法,BeanFactory的後置處理器
// 在BeanFactory标準初始化之後執行的,調用各種BeanFactoryPostProcessor
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注冊BeanPostProcessor(Bean的後置處理器),用于攔截bean建立過程
this.registerBeanPostProcessors(beanFactory);
// 初始化MessageSource元件(做國際化功能;消息綁定,消息解析).
this.initMessageSource();
// 初始化上下文的事件機制
this.initApplicationEventMulticaster();
// 可以用于子類實作在容器重新整理時自定義邏輯初始化
this.onRefresh();
// 注冊時間監聽器,将ApplicationListener注冊到容器中來
this.registerListeners();
// 初始化所有剩下的單執行個體bean,單例bean在初始化容器時建立。
this.finishBeanFactoryInitialization(beanFactory);
// 釋出完成事件,結束初始化過程
this.finishRefresh();
}
catch (BeansException ex) {
...
}
}
}
複制代碼