传统tomcat启动服务与springboot启动内置tomcat服务的区别
(推荐)
spring整合springmvc
spring整合springmvc中l配置如下,tomcat在启动过程中会加载l中的内容,ContextLoaderListener实现了tomcat⾥⾯的ServletContextListener接⼝,所以在tomcat容器启动过程通过ContextLoaderListener来进⾏spring容器的初始化操作,并将
classpath:spring/applicationContext-*.xml指定下的spring配置⽂件加载,该配置⽂件我只配置了<context:component-scan base-
package=“org.yp”/>,代表通过扫描org.yp包下的类,包含@Component @Controller@Service等注解等类,进⾏bean注册。
bean注册是通过AbstractXmlApplicationContext.loadBeanDefinitions该类的⽅法进⾏bean定义加载的。
spring中加载bean定义是在t.ConfigurableApplicationContext#refresh⽅法中的ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()⽅法加载bean的,该⽅法之后会调⽤
t.support.AbstractRefreshableApplicationContext#refreshBeanFactory⽅法创建bean⼯⼚,并加载的bean定义。<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="/2001/XMLSchema-instance"
xmlns="java.sun/xml/ns/javaee"
xsi:schemaLocation="java.sun/xml/ns/javaee
java.sun/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.t.ContextLoaderListener</listener-class>
</listener>
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springMVC需要加载的配置⽂件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<!-- 默认匹配所有的请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
当tomcat容器启动后,通过路径访问资源时,第⼀次会调⽤org.springframework.web.servlet.HttpServletBean#init⽅法,之后的http请求就不会再⽅法该⽅法类;HttpServletBean实现了Servlet接⼝的规范,所以经过浏览器的请求经过servlet接⼝初始化执⾏init⽅法时,会再从spring容器中去加载springmvc配置中定义的加载类,spring与springmvc是⽗⼦容器的关系,下⾯是HttpServletBean的init⽅法
public final void init() throws ServletException {
// Set bean properties from init parameters.
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), quiredProperties);
if (!pvs.isEmpty()) {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
if (logger.isErrorEnabled()) {
<("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
}
servlet和tomcat的关系throw ex;
}
}
// 最后会调⽤t.ConfigurableApplicationContext#refresh容器的刷新⽅法,
// 进⾏springmvc容器初始化
initServletBean();
}
}
springboot启动容器
springboot启动的⽅式则是先在springboot的org.springframework.boot.SpringApplication#run(java.lang.String…)⽅法中就初始化了spring的上下⽂环境(⾥⾯包含bean⼯⼚),之后通过org.springframework.boot.SpringApplication#refreshContext⽅法调⽤Spring容器中的
ConfigurableApplicationContext#refresh⽅法初始化bean.
在spring与springmvc整合的环境中,bean定义的加载是在
t.support.AbstractApplicationContext#obtainFreshBeanFactory⽅法,⽽springboot中是在
t.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors⽅法,该⽅法中通过ConfigurationClassPostProcessor类去加载bean定义,该类实现了BeanDefinitionRegistryPostProcessor接⼝,这个接⼝允许对bean定义进⾏加⼯处理。
// spring中的BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的⼦接⼝,
/
/ BeanFactoryPostProcessor的作⽤是在bean的定义信息已经加载但还没有初始化的时候执⾏⽅法postProcessBeanFactory()⽅法,
// ⽽BeanDefinitionRegistryPostProcessor是在BeanFactoryPostProcessor的前⾯执⾏,在源码
// t.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()⽅法⾥⾯定义了执⾏顺序
// BeanFactoryPostProcessor是bean⼯⼚的bean属性处理容器,说通俗⼀些就是可以管理我们的bean⼯⼚内所有的beandefinition(未实例化)数据,可以随⼼所欲的修改属性。public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
//获取告诉⼦类初始化Bean⼯⼚将bean加载到缓存中 spring springmvc整合是在这初始化bean的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
// springboot容器启动加载到这时,初始化了下⾯⼏个bean name
//0 = "t.annotation.internalConfigurationAnnotationProcessor" =》对应ConfigurationClassPostProcessor类
//1 = "t.annotation.internalAutowiredAnnotationProcessor" =》 AutowiredAnnotationBeanPostProcessor
//2 = "t.annotation.internalCommonAnnotationProcessor" =》 CommonAnnotationBeanPostProcessor
//3 = "t.event.internalEventListenerProcessor" =》 EventListenerMethodProcessor
/
/4 = "t.event.internalEventListenerFactory" =》 DefaultEventListenerFactory
// 调⽤我们的bean⼯⼚的后置处理器.加载bean定义(不是实例化),通过ConfigurationClassPostProcessor去加载启动类中的扫描路径
// 然后将路径下到bean加载进来
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
// 这个⽅法同样也是留个⼦类实现的springboot也是从这个⽅法进⾏启动tomat的.
onRefresh();
registerListeners();
//实例化我们剩余的单实例bean.
finishBeanFactoryInitialization(beanFactory);
// 最后容器刷新发布刷新事件(Spring cloud也是从这⾥启动的)
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
resetCommonCaches();
}
}
}
到此这篇关于传统tomcat启动服务与springboot启动内置tomcat服务的区别的⽂章就介绍到这了,更多相关tomcat启动服务与springboot启动内置tomcat服务区别内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论