springboot2.0.6如何创建应用程序,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
public ConfigurableApplicationContext run(String... args) {
......//省略
ConfigurableApplicationContext context = null;
......//省略
try {
......//省略
// 根据应用类型创建对应的Context容器
context = createApplicationContext();
......//省略
// 刷新Context之前的准备
// 将SpringApplicationRunListeners、ConfigurableEnvironment、ApplicationArguments、Banner等重要组件与上下文对象关联
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
......//省略
}
......//省略
} catch (Throwable ex) {
// 启动错误报告处理
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
......//省略
}
应用上下文环境是什么,都包括那些呢?其可以理解成SpringIoC容器的升级,即其在IoC容器的基础上丰富了一些高级功能,而且其对IoC容器是持有关系。它的beanFactory就是IoC容器。其包括运行系统环境、Java环境、Spring运行环境、项目配置、启动指令等等。在SpringBoot中应用类型分三种,如下面枚举中所示
public enum WebApplicationType {
/**
* 应用程序不是web应用,也不应该用web服务器去启动
*/
NONE,
/**
* 应用程序应作为基于servlet的web应用程序运行,并应启动嵌入式servlet web(tomcat)服务器。
*/
SERVLET,
/**
* 应用程序应作为 reactive web应用程序运行,并应启动嵌入式 reactive web服务器。
*/
REACTIVE
}
对应不同的应该类型,SpringBoot给出了三种对应的应用上下文。
从结构上看它们都继承了GenericApplicationContext,而GenericApplicationContext中定义了beanFactory
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
...
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
...
}
从上面结构可知当我们初始化了应用上下文时,同样也触发了GenericApplicationContext类的构造函数,从而创建了IoC容器。仔细看他的构造函数,有没有发现一个很熟悉的类DefaultListableBeanFactory,这个DefaultListableBeanFactory就是IoC容器真实面目了。在后面的refresh()方法分析中,DefaultListableBeanFactory是无处不在的。
我们可以调用createApplicationContext方法根据应用类创建具体的applicationContext
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
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);
}
}
// 根据Class创建Application
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
以web工程为例,其上下文为AnnotationConfigServletWebServerApplicationContext
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 走 clazz.getDeclaredConstructor 方法
Constructor<T> ctor = (KotlinDetector.isKotlinType(clazz) ?
KotlinDelegate.getPrimaryConstructor(clazz) : clazz.getDeclaredConstructor());
return instantiateClass(ctor);
}
......//省略
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
// 走 clazz.newInstance方法
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
......//省略
}
初始化上下文实例结果如下
看完上述内容,你们掌握springboot2.0.6如何创建应用程序的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/267665/blog/3120938