1.这2天学了一下spring boot,为了扫盲spring cloud,记录学习心得。
2. 第一天简单回答几个问题:
(1)spring boot是如何内嵌tomcat容器的。
解答:这个我没看代码也大概猜到了,因为以前看ClassPathXmlApplicationContext源码的时候,AbstractApplicationContext的refresh()方法是有很多预留的扩展方法的,不出所料,spring boot正式通过AnnotationConfigEmbeddedWebApplicationContext类实现onRefresh()的方式内嵌tomcat容器的
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
AnnotationConfigEmbeddedWebApplicationContext类实现onRefresh(),默认取得是TomcatEmbeddedServletContainer,可以切换到jetty 。
@Override
protected void onRefresh() {
super.onRefresh();
try {
createEmbeddedServletContainer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start embedded container",
ex);
}
}
/**
* Create a new {@link TomcatEmbeddedServletContainer} instance.
* @param tomcat the underlying Tomcat server
* @param autoStart if the server should be started
*/
public TomcatEmbeddedServletContainer(Tomcat tomcat, boolean autoStart) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
initialize();
}
private synchronized void initialize() throws EmbeddedServletContainerException {
TomcatEmbeddedServletContainer.logger
.info("Tomcat initialized with port(s): " + getPortsDescription(false));
try {
addInstanceIdToEngineName();
// Remove service connectors to that protocol binding doesn't happen yet
removeServiceConnectors();
// Start the server to trigger initialization listeners
this.tomcat.start();
// We can re-throw failure exception directly in the main thread
rethrowDeferredStartupExceptions();
// Unlike Jetty, all Tomcat threads are daemon threads. We create a
// blocking non-daemon to stop immediate shutdown
startDaemonAwaitThread();
}
catch (Exception ex) {
throw new EmbeddedServletContainerException("Unable to start embedded Tomcat",
ex);
}
}
切换到jetty也很简单:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除默认的tomcat,引入jetty容器. -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- jetty 容器. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
(2)spring boot是如何注册bean到容器里面的:
解答:一般情况下,DefaultListableBeanFactory或者ClassPathXmlApplicationContext注册bean到容器都是通过解析XML默认标签和自定义标签的方式注册bean到容器里面的,最终存到DefaultListableBeanFactory的Map<String, BeanDefinition> beanDefinitionMap =new ConcurrentHashMap<String, BeanDefinition>(256);对象中的,而springboot是通过
"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"注册bean到容器中的,具体源码如下:
核心代码: load(context, sources.toArray(new Object[sources.size()]));
private ConfigurableApplicationContext createAndRefreshContext(
SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
ConfigurableApplicationContext context;
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared(environment);
if (isWebEnvironment(environment) && !this.webEnvironment) {
environment = convertToStandardEnvironment(environment);
}
if (this.bannerMode != Banner.Mode.OFF) {
printBanner(environment);
}
// Create, load, refresh and run the ApplicationContext
context = createApplicationContext();
context.setEnvironment(environment);
postProcessApplicationContext(context);
applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
context.getBeanFactory().registerSingleton("springApplicationArguments",
applicationArguments);
// Load the sources
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[sources.size()]));
listeners.contextLoaded(context);
// Refresh the context
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
return context;
}
分享到:
相关推荐
springboot2.4增删改查示例,结合B站尚硅谷教程使用,给初学者使用,spingboot2.4相较于1.5版本的用法有些变化,经验者绕行。
spring-boot-cli-2.0.3.RELEASE-bin,初学者可以直接拿去使用
Spring Boot 是在 Spring 的基础上创建一款开源框架,它提供了 spring-boot-starter-web(Web 场景启动器) 来为 Web 开发予以支持。spring-boot-starter-web 为我们提供了嵌入的 Servlet 容器以及 SpringMVC 的依赖...
Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用。 本项目中所有示例均已经更新到 Spring Boot 3.0 ...
•Spring Boot CLI: 使用CLI •核心特性: SpringApplication |外部配置|概要|日志 •Web应用:MVC |嵌入式容器 •处理数据:SQL | NO-SQL •消息传递:概述| JMS •测试:概述|引导应用| Utils •扩展:自动配置| @...
适合初学 springboot 的同学 --------------------------- maven配置:pom.xml --------------------------- <?xml version="1.0"?> ...
整合mybatis-spring-boot-2.0-shiro-thymeleaf 简短的小demo,适合初学者
根据mybatis插件生成的代码加上spring boot集成,初学者者可以看看。
apache-maven
Spring Shiro 学习系统 Spring-Shiro-training,适合初学者。
spring的安全框架演示demo,这个是简单的,适合初学者
本人springboot学习笔记总结,根据视频初学,感兴趣可下载。
Spring Boot学习范例 Spring Boot使用的各种示例,以最简单,最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握Spring Boot各个组件的使用。 | | | ||推荐程序员都关注的一个...
该资源集成了spring boot和mybatis,并且其中包含代码生成器,初学者非常适合,可以下载资源,后续有问题留言沟通
作为初学者,我发现将 Akka 与 Spring 的依赖注入集成有点复杂,尤其是在我使用 Java 时。 这个应用程序是向前迈出的一步,但以一种非常简单的方式(而不是使用 Spring Extension 和 ApplicationConfiguration 代码...
初学者所需的五个jar包,commons-logging-1.2,spring-beans-5.05.RELEASE,spring-core-5.0.5.RELEASE,spring-jdbc-5.0.5.RELEASE,spring-jdbc-5.0.5.RELEASE-sources,
drools的spring boot demo 初学者,大家一起学习吧,我
SpringBoot基础实践Demo,SpringBoot初学者。
fabric-gateway-spring-boot-starter :一个 spring MVC 启动器。 fabric-explorer-spring-boot-starter :一个简单的 Fabric Explorer 启动器。 如何使用 Spring Boot 配置: 首先,将以下依赖项添加到项目的pom....
该代码为springboot初学者提供了一个快速实践案例,工程使用springboot+Springmvc+mytabis的架构搭建了一套主流的java web项目,参照代码初学者可以快速入门当前主流web开发。