我們知道叫搁,當(dāng):
AnnotationConfigApplicationContext al=new AnnotationConfigApplicationContext(appconfig.class);
//appconfig這個(gè)類是個(gè)spring配置類,加了@Configuration,@ComponentScan("packgename")這兩個(gè)注解。
此方法初始化了spring容器
下面一探源碼:
/**
* 這個(gè)構(gòu)造方法需要傳入一個(gè)被javaconfig注解了的配置類
* 然后會(huì)把這個(gè)被注解了javaconfig的類通過(guò)注解讀取器讀取后繼而解析
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//annotatedClasses appconfig.class
//這里由于他有父類悠轩,故而會(huì)先調(diào)用父類的構(gòu)造方法火架,然后才會(huì)調(diào)用自己的構(gòu)造方法
//在自己構(gòu)造方法中初始一個(gè)讀取器和掃描器
this();
register(annotatedClasses);//方法一
refresh();//方法二
}
先初始化父類的構(gòu)造器何鸡,注意父類GenericApplicationContext的無(wú)參構(gòu)造器是實(shí)例化BeanFactory
DefaultListableBeanFactory這個(gè)類就是spring的bean工廠
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
* 一個(gè)工廠
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
然后this()調(diào)用自己的無(wú)參構(gòu)造牛欢,無(wú)參構(gòu)造代碼如下:
/**
* 初始化一個(gè)bean的讀取和掃描器
* 何謂讀取器和掃描器參考上面的屬性注釋
* 默認(rèn)構(gòu)造函數(shù),如果直接調(diào)用這個(gè)默認(rèn)構(gòu)造方法隔盛,需要在稍后通過(guò)調(diào)用其register()
* 去注冊(cè)配置類(javaconfig)拾稳,并調(diào)用refresh()方法刷新容器,
* 觸發(fā)容器對(duì)注解Bean的載入龙亲、解析和注冊(cè)過(guò)程
* 這種使用過(guò)程我在ioc應(yīng)用的第二節(jié)課講@profile的時(shí)候講過(guò)
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
/**
* 父類的構(gòu)造方法
* 創(chuàng)建一個(gè)讀取注解的Bean定義讀取器
* 什么是bean定義鳄炉?BeanDefinition
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
//可以用來(lái)掃描包或者類传趾,繼而轉(zhuǎn)換成bd
//但是實(shí)際上我們掃描包工作不是scanner這個(gè)對(duì)象來(lái)完成的
//是spring自己new的一個(gè)ClassPathBeanDefinitionScanner
//這里的scanner僅僅是為了程序員能夠在外部調(diào)用AnnotationConfigApplicationContext對(duì)象的scan方法
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
首先看看構(gòu)造方法里的第一個(gè)方法
this.reader = new AnnotatedBeanDefinitionReader(this);這句代碼,構(gòu)造方法參數(shù)是BeanDefinitionRegistry,而傳的是this,表示AnnotationConfigApplicationContext是BeanDefinitionRegistry的子類磕仅。
AnnotatedBeanDefinitionReader這個(gè)類是BeanDefinition讀取器,給它一個(gè)java類榕订,它會(huì)解析成描述這個(gè)類的BeanDefinition,但是這個(gè)類只會(huì)解析加了注解的類劫恒,下面查看該方法的調(diào)用鏈:
/**
* 這里的BeanDefinitionRegistry registry是通過(guò)在AnnotationConfigApplicationContext
* 的構(gòu)造方法中傳進(jìn)來(lái)的this
* 由此說(shuō)明AnnotationConfigApplicationContext是一個(gè)BeanDefinitionRegistry類型的類
* 何以證明我們可以看到AnnotationConfigApplicationContext的類關(guān)系:
* GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
* 看到他實(shí)現(xiàn)了BeanDefinitionRegistry證明上面的說(shuō)法,那么BeanDefinitionRegistry的作用是什么呢丛楚?
* BeanDefinitionRegistry 顧名思義就是BeanDefinition的注冊(cè)器
* 那么何為BeanDefinition呢趣些?參考BeanDefinition的源碼的注釋
* @param registry
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
再往里:
/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
* the given {@link Environment}.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @param environment the {@code Environment} to use when evaluating bean definition
* profiles.
* @since 3.1
*/
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);
}