前面的話
前面兩篇文章主要是走讀了springboot啟動(dòng)時(shí)的準(zhǔn)備階段,本文正式進(jìn)入重點(diǎn)的階段摇邦。即spring context的生成汞窗。即如下代碼:
//生成spring的context
context = createApplicationContext();
// 異常上報(bào)
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);
//準(zhǔn)備spring context
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//組裝spring context,這一步是重點(diǎn)刊苍。主要是spring的機(jī)制
refreshContext(context);
下面來(lái)分別走讀每行代碼既们。
createApplicationContext
createApplicationContext的代碼如下:
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
根據(jù)不同的webType初始化不同的context。如果是servlet正什,則通過(guò)反射啥纸,初始化org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
,如果是reactive類型,則初始化org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext
,如果都不是上面的類型婴氮,則初始化org.springframework.context.annotation.AnnotationConfigApplicationContext
.
本文主要走讀servlet類型斯棒。下面主要看AnnotationConfigServletWebServerApplicationContext
的類圖。
這里看下初始化AnnotationConfigServletWebServerApplicationContext
干了哪些事情主经。
由于該類繼承了GenericApplicationContext
荣暮,GenericApplicationContext
中的構(gòu)造方法里初始化了beanfactory。
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
這里直接new出一個(gè)DefaultListableBeanFactory
出來(lái)旨怠。
AnnotationConfigServletWebServerApplicationContext
的無(wú)參構(gòu)造方法里做了哪些事情呢渠驼?
public AnnotationConfigServletWebServerApplicationContext() {
//注解相關(guān)的處理
this.reader = new AnnotatedBeanDefinitionReader(this);
//scan相關(guān)處理
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
初始化reader和scanner。具體做的事情是什么呢鉴腻?
new AnnotatedBeanDefinitionReader(this);
的代碼如下:
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);
}
代碼中this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
是注冊(cè)Conditional注解家族的處理類迷扇。Conditional注解主要作用是百揭,注冊(cè)滿足條件的bean,Conditional注解家族有如下成員:
當(dāng)然蜓席,我們也可以自定義條件器一,只需要實(shí)現(xiàn)
Condition
接口。定義如下:
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
然后在使用的時(shí)候厨内,在類或者方法上使用@Conditional(yourconditon.class)
代碼中AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
主要是實(shí)例化spring相關(guān)注解的bean祈秕。
代碼如下
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//@Order的處理bean
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//@Lazy,@Qualifier的處理bean
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//@Configuration 注解的bean注冊(cè)
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 和@Value注解的bean注冊(cè)雏胃。
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.
//java 自有注解的處理请毛,如@Resource,@PostConstruct瞭亮,@PreDestroy等
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.
// JPA相關(guān)注解的處理
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));
}
//@EventListener注解的處理
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));
}
// 事件工廠的默認(rèn)實(shí)現(xiàn)
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;
}
接下來(lái)方仿,走讀this.scanner = new ClassPathBeanDefinitionScanner(this);
代碼如下:
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();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
這段代碼主要是注冊(cè)掃描的默認(rèn)過(guò)濾規(guī)則,默認(rèn)規(guī)則掃描@Component ,@Repository,@Service,@Controller等及JAVAEE6的@ManagedBean和JSR-330的@Named统翩。
至此仙蚜,context的初始化算是告一段落了,總結(jié)下來(lái)厂汗,在初始化context時(shí)委粉,做了哪些事情呢?
1娶桦、通過(guò)webType贾节,獲取不同的context class,這里以servlet為例走讀趟紊。通過(guò)反射初始化AnnotationConfigServletWebServerApplicationContext
2氮双、在context例初始化beanFactory。new一個(gè)DefaultListableBeanFactory霎匈。
3、注冊(cè)bean的處理類送爸。如:conditional铛嘱,@order,@lazy袭厂,@autowared等注解的處理墨吓。
4、注冊(cè)掃描規(guī)則等纹磺。