Spring源码之Context的创建核心逻辑(上)
我们前一章介绍了spring的整体架构以及模块划分,也已经将代码导入ide中,那么接下来就要开始让人心动的Spring源码之旅了。
1、默认的Spring启动器
@SpringBootApplication
@ComponentScan(basePackages = {"com"})
public class SpringSourceApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(SpringSourceApplication.class, args);
}
}
该方法是Springboot的启动类
2、进入SpringApplication.java
public static ConfigurableApplicationContext run(Object source, String... args) {
return run(new Object[] { source }, args);
}
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
这里创建了一个SpringApplication方法,执行run方法,返回一个ConfigurableApplicationContext,这只是一个接口而已,根据名称来看,这是一个可配置的应用程序上下文。
3、进入RUN方法
SpringApplication(sources)这个类的初始化就先不看,这里面调用了initialize()方法,主要完成了当前的运行环境,以及设置了ApplicationListener相关的东西,这里我们先不做分析,直接进入run方法。
public ConfigurableApplicationContext run(String... args) {
//记录程序运行时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
/**
* 设置headless模式
* 在我们的例子中该属性会被设置为true,因为我们开发的是服务器程序,
* 一般运行在没有显示器和键盘的环境。关于java中的headless模式
*/
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
bindToSpringApplication(environment);
Banner printedBanner = printBanner(environment);
/**
* 它创建出来的是ConfigurableApplicationContext类的实例对象
*AnnotationConfigEmbeddedWebApplicationContext
*/
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
/**
* 该方法对context进行了预设置,设置了ResourceLoader和ClassLoader,
* 并向bean工厂中添加了一个beanNameGenerator
*/
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
/**
* prepareContext()已经做好了refresh上下文的基础准备工作
* spring对ApplicationContext进行了向下转型,
* 转型后的类型为:AbstractApplicationContex,并调用了它的refresh()方法
* 详见方法内部实现
*/
refreshContext(context);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
try代码块中是我们最核心的功能,代码中也添加了一部分的注释。我们先看context的创建过程即进入到createApplicationContext()方法。
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
//此处采用反射获取WebApplicationContext
contextClass = Class.forName(DEFAULT_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);
}
DEFAULT_WEB_CONTEXT_CLASS—>AnnotationConfigEmbeddedWebApplicationContext
接下来执行AnnotationConfigEmbeddedWebApplicationContext的构造方法
public AnnotationConfigEmbeddedWebApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
上面实例化了 AnnotatedBeanDefinitionReader
以及 ClassPathBeanDefinitionScanner
实例化 AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
接下来是调用
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
,将其属性 ConditionContextImpl
赋值
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
具体实现如下:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//获取beanfactory信息,Spring IOC的核心
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<>(4);
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));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_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;
}
上面代码比较长,我们来分开解析
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
由wrap就可以看出此处使用的是装饰器模式,registry包裹成一个指定的beanFactory
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {
if (registry instanceof DefaultListableBeanFactory) {
return (DefaultListableBeanFactory) registry;
}
else if (registry instanceof GenericApplicationContext) {
//此处 GenericApplicationContext构造函数初始化beanFactory为DefaultListableBeanFactory
return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();
}
else {
return null;
}
}
代码执行到`registry instanceof GenericApplicationContext`(通过类继承结构可得到),随后调用`GenericApplicationContext#getDefaultListableBeanFactory()方法,GenericApplicationContext`在构造方法中实例化了属性`beanFactory`的值为`DefaultListableBeanFactory`:
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
其构造优先于`AnnotationConfigEmbeddedWebApplicationContext`构造方法执行。
以上获得了BeanFactory信息
代码的构建请参考 github该地址有相应代码的注释
Spring源码分析
上一篇:程序员高效工具
点击原文阅读更多