1. 註冊過程解析(語言層面)
-
解析說明
由於spring代碼加載過程非常複雜,在此先通過語言描述大體介紹對象註冊進spring容器的過程,下面會通過解析spring中重點源碼來分析每一步驟
-
創建spring容器:
new AnnotationConfigApplicationContext()
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); refresh(); }
-
執行AnnotationConfigApplicationContext父類構造方法,即創建bean工廠:
new DefaultListableBeanFactory()
-
執行構造方法中this()方法:主要創建了
AnnotatedBeanDefinitionReader
和ClassPathBeanDefinitionScanner
兩個類1.AnnotatedBeanDefinitionReader: 執行構造方法,完成後置處理器的創建,轉爲beanDefinition,重點關注
ConfigurationClassPostProcessor
2.ClassPathBeanDefinitionScanner: 掃描類路徑下bean,並將其變爲beanDefinition交註冊進spring容器 -
執行構造方法中register(componentClasses)方法: 完成後置處理器(spring創建,自定義)的創建,傳入配置類轉換爲beanDefinition並註冊至spring容器
-
執行構造方法中refresh()方法: 解析配置類,將所有自定義對象掃描、解析並轉換爲beanDefinition,最終註冊至spring容器
2. 註冊過程解析(代碼層面)
2.1 構造方法解析
AnnotationConfigApplicationContext acc = new AnnotationConfigApplicationContext(AppConfig.class);
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
構造方法中包含以下三部份:
1. this(): 創建spring的bean工廠(DefaultListableBeanFactory)
2. register(): 創建spring所需後置處理器(beanPostProcessor,beanFactoryPostProcessor),同時將創建的後置處理器、自定義配置類註冊進spring容器
3. refresh(): 解析註冊進spring容器的配置類,根據配置的componScan地址解析基礎包下自定義bean,並將解析的bean註冊進spring容器
2.2 this()方法解析
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
解析方法:
1.AnnotationConfigApplicationContext繼承至GenericApplicationContext,則執行父類構造方法,創建bean工廠(DefaultListableBeanFactory)
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
2.執行AnnotatedBeanDefinitionReader()構造方法,調用registerAnnotationConfigProcessors方法,創建spring內置beanPostProcessor和BeanFactoryPostProcessor
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);
// 註冊spring內置五個後置處理器
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));
}
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;
}
1.創建spring內置處理器,其中重點關注ConfigurationClassPostProcessor,該後置處理器用於處理添加了@Configuration註解配置類
2.執行registerPostProcessor()
將創建的內置處理器註冊至spring容器中
3.ConfigurationClassPostProcessor繼承至beanFactoryPostProcessor
,其餘4個後置處理器實現beanPOstProcessor
,後續會介紹兩者差異
執行結果::
3.ClassPathBeanDefinitionScanner:掃描bean,並將其轉爲beanDefinition同時註冊至spring容器中,我們用不了,在此就不做解析
2.3 register()方法解析
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
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));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
1.創建AnnotatedGenericBeanDefinition,所有註解類均使用該beanDefinition
2.設置註解BeanDefinition元數據和通用註解黙認值,包含scope
,lazy
,Description
等
3.將beanDefinition包裝成BeanDefinitionHolder,無實際意義,便於傳參
4.執行BeanDefinitionReaderUtils.registerBeanDefinition()將傳入配置類註冊至spring容器
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
配置類註冊進spring容器過程如下圖:
執行結果如下,從下圖可看出執行完register()方法後,beanDefinitionMap中增加了appConfig的映射
2.4 refresh()方法解析
refresh()主要解析自定義後置處理器、自定義對象註冊至spring容器,涉及動西較多,詳情見文章
spring源碼分析| 第二篇:自定義後置處理器及自定義對象註冊解析