Spring 5.x 源碼之旅一AnnotatedBeanDefinitionReader
- 前言
- 簡單注解例子
- 簡單思考
- AnnotationConfigApplicationContext注解配置上下文
-
- 先看下大緻建立了什麼
- AnnotatedBeanDefinitionReader讀取器
-
- getOrCreateEnvironment獲得或者建立環境
- AnnotatedBeanDefinitionReader構造方法
- 重要屬性
- AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)注冊注解配置處理器
- AnnotationConfigUtils的registerPostProcessor注冊後置處理器
-
- GenericApplicationContext的registerBeanDefinition注冊bean定義
-
- DefaultListableBeanFactory的registerBeanDefinition注冊bean定義
- BeanDefinitionHolder封裝bean定義而已
前言
前面寫了一些
netty
的源碼解析,雖然覆寫不了所有的内容,但是大部分核心的内容都講到了,主要還是要自己去看,去了解,然後寫點小
demo
,領會
netty
的設計意圖,為什麼能高性能,從線程的分工明确,多路複用到記憶體配置設定的分而治之,讓多線程之間減少競争,讓記憶體使用效率提高,等等一些思想。現在想再分析下
Spirng 5.2.1.RELEASE
的源碼,雖然這個很複雜,但是我們還是可以大緻了解一些原理,對以後使用和問題定位都有所幫助,而且還可以學到一些思想,一些處理方法,一些設計模式等等。我們主要是研究注解使用的一些原理。
簡單注解例子
首先我們建立一個配置類
MyConfig
:
@Configuration
public class MyConfig {
}
然後寫一個測試方法,友善我們調試:
@Test
public void BeanDefinitionRegistryPostProcessorTest0() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
}
啥都不幹,就分析他對配置類做了什麼。
簡單思考
先不看源碼,我們自己思考下我們把一個配置類放進去,他可能會做點什麼。假設我們都用過
Spring
,哪怕最簡單的那種,很明顯我們可以猜到,他裡面應該是對我們注解
@Configuration
的類進行了解析,分析他裡面有點什麼,然後進行相應的處理。确實大緻思路就這樣,但是具體就比較複雜了,我們還是看源碼慢慢分析吧。
AnnotationConfigApplicationContext注解配置上下文
先看下大緻建立了什麼
首先我們看名字隻知道他是注解配置的上下文,也就是一個環境,那環境裡面應該有好多東西,可以處理我們傳進去的類。我們剛才調用的構造方法就是這個:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
首先他先建立了一個
DefaultListableBeanFactory
,這個就是後面一直要用的
bean
工廠,裡面放着所有和
bean
相關的東西,比如
bean
定義,bean後置處理器等等,其實spring的思想就是把你給他的類都需要一個
bean
定義來描述,這樣才可以進行處理。然後再建立
AnnotatedBeanDefinitionReader
和
ClassPathBeanDefinitionScanner
,一個是注解的
bean
定義讀取器,一個是
bean
定義的掃描器。這裡要注意
ClassPathBeanDefinitionScanner
其實是提供給使用者用的,并不是他内部使用,内部後面他會再建立一個來用。我們先來看下
AnnotatedBeanDefinitionReader
建立做了什麼。
AnnotatedBeanDefinitionReader讀取器
看這個構造方法,傳入的是一個
BeanDefinitionRegistry
類型,就是可以注冊
bean
定義的,内部要注冊就需要用到。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
getOrCreateEnvironment獲得或者建立環境
如果
BeanDefinitionRegistry
是
EnvironmentCapable
的話就可以直接擷取,否則就建立一個标準環境,其實就是擷取一些系統的變量。比如可以配置
dev
環境,
test
環境,
online
環境等等。
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();
}
AnnotatedBeanDefinitionReader構造方法
對
BeanDefinitionRegistry
進行了儲存和把
environment
封裝進了
ConditionEvaluator
,
ConditionEvaluator
可以了解成一個條件過濾器,與
@Conditional
有關,如果有了這個注解,就先判斷條件成不成立,不成立的話有些操作就不做了。
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);
}
重要屬性
另外有三個屬性後面會用到,比如
bean
的名字生成器
BeanNameGenerator
,可以自定義怎麼生成,預設是簡單類名首字母小寫,還有一個是範圍注解的解析器
ScopeMetadataResolver
,解析出範圍,是單例,還是原型,另一個就是條件評估器了
ConditionEvaluator
:
private final BeanDefinitionRegistry registry;
//類名生成器
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
//socpe注解解析器
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
//條件評估器
private ConditionEvaluator conditionEvaluator;
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)注冊注解配置處理器
這個一看方法就知道要加一些處理器,來處理我們的注解,也就是說,
spring
有些内部的處理器需要注冊進來,這裡可以想到
spring
應該是為了統一處理處理器,是以也是按注冊,處理這樣的流程來,無論是自己内部的,還是使用者自定義的,我們來看看裡面是怎麼做的。
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
主要流程就是擷取
DefaultListableBeanFactory
,然後注冊
AnnotationAwareOrderComparator
順序比較器,排序用的,
ContextAnnotationAutowireCandidateResolver
自動裝配解析器,解析自動裝配相關配置用。然後建立一些後置處理器的
bean
定義,内部一般用
RootBeanDefinition
來定義,比如這個類
ConfigurationClassPostProcessor
,他是前面配置類處理的關鍵,是以這裡先添加
bean
定義,還有
AutowiredAnnotationBeanPostProcessor
,處理自動裝配的,另外還有
EventListenerMethodProcessor
和
DefaultEventListenerFactory
,
CommonAnnotationBeanPostProcessor
暫時不講,後面用到會說。
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());//設定自動裝配解析器
}
}
//建立BeanDefinitionHolder集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//設定ConfigurationClassPostProcessor後置處理器
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;
}
AnnotationConfigUtils的registerPostProcessor注冊後置處理器
注冊後置處理器,其實是注冊對應的
bean
定義,對于一些内部處理器的
bean
定義,會設定角色屬性
setRole
,然後向
registry
裡注冊
beanName
和
bean
定義,最後封裝成
BeanDefinitionHolder
傳回。
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);//注冊進registry
return new BeanDefinitionHolder(definition, beanName);
}
GenericApplicationContext的registerBeanDefinition注冊bean定義
可以看到,這裡出現了
beanFactory
,就是我們開始獲得的
DefaultListableBeanFactory
,注冊
bean
定義是交給他的。
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
DefaultListableBeanFactory的registerBeanDefinition注冊bean定義
其他非核心的暫時略過了,剩下就兩行,最終是把他放入
ConcurrentHashMap
中,名字放入
ArrayList
中。放在
map
裡是為了後面可以友善映射擷取,名字在
list
中則是為了友善擷取周遊。
...
this.beanDefinitionMap.put(beanName, beanDefinition);//名字和bean定義對應
this.beanDefinitionNames.add(beanName);//名字
...
BeanDefinitionHolder封裝bean定義而已
這個類其實就是對
beanName
和
bean
定義和别名做了封裝:
最後注解配置處理器注冊完成,注冊了比較器和解析器,注冊了注解處理器
bean
定義:
可以看到,内部的
bean
定義全部都是用
RootBeanDefinition
,關于
bean
定義的類型後面會說,先了解就行。至此讀取器建立完成,其實就是注冊了需要處理注解的處理器
bean
定義,此時還沒有建立
bean
哦。後面
ConfigurationClassPostProcessor
發揮着很大的作用,用來解析配置類。後面我們要先了解下
spring
裡的
bean
定義到是定義什麼。
好了,今天就到這裡了,希望對學習了解有幫助,大神看見勿噴,僅為自己的學習了解,能力有限,請多包涵。