在Servlet容器启动会将所有实现ServletContainerInitializer接口的类添加到StandardContext的initializers集合中,然后循环调用onStartup方法。
Spring的SpringServletContainerInitializer类就实现了ServletContainerInitializer接口,
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { @Override public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>(); if (webAppInitializerClasses != null) { for (Class<?> waiClass : webAppInitializerClasses) { // Be defensive: Some servlet containers provide us with invalid classes, // no matter what @HandlesTypes says... if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer) waiClass.newInstance()); } catch (Throwable ex) { throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex); } } } } if (initializers.isEmpty()) { servletContext.log("No Spring WebApplicationInitializer types detected on classpath"); return; } servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath"); AnnotationAwareOrderComparator.sort(initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } } }
该类上@HandlesTypes该注解表示容器会读取@HandlesTypes注解value值。并放入 initializers 对应的集合中,循环调用WebApplicationInitializer类型onStartup方法。进而容器初始化将Listener,Servlet,Filter注册到servet容器中。
Spring提供扩展了Servlet初始化扩展类,其中AbstractAnnotationConfigDispatcherServletInitializer类为注解配置形式扩展抽象类。所以我们可以继承该类进行定制化配置
WebInitializer AbstractAnnotationConfigDispatcherServletInitializer { Class<?>[] () { Class[] {ApplicationContextConfig.}} Class<?>[] () { Class[] {WebMvcConfig.}} String[] () { String[] {}} (ServletContext servletContext) { servletContext.setInitParameter()servletContext.addListener(LogbackConfigListener.).registerContextLoaderListener(servletContext)} }
SpringMVC容器相关配置
com.alibaba.fastjson.serializer.SerializerFeaturecom.alibaba.fastjson.support.config.FastJsonConfigcom.alibaba.fastjson.support.spring.FastJsonHttpMessageConverterorg.springframework.context.annotation.org.springframework.context.annotation.org.springframework.context.annotation.FilterTypeorg.springframework.http.MediaTypeorg.springframework.http.converter.HttpMessageConverterorg.springframework.stereotype.org.springframework.web.bind.annotation.org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurerorg.springframework.web.servlet.config.annotation.org.springframework.web.servlet.config.annotation.ViewResolverRegistryorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapterjava.util.ArrayListjava.util.List(={}=={(=FilterType.={..})}) WebMvcConfig WebMvcConfigurerAdapter { (DefaultServletHandlerConfigurer configurer) { configurer.enable()} (ViewResolverRegistry registry) { registry.jsp()} (List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastConverter = FastJsonHttpMessageConverter()FastJsonConfig fastJsonConfig = FastJsonConfig()fastJsonConfig.setSerializerFeatures(SerializerFeature.)List<MediaType> fastMediaTypes = ArrayList<>()fastMediaTypes.add(MediaType.)fastConverter.setFastJsonConfig(fastJsonConfig)fastConverter.setSupportedMediaTypes(fastMediaTypes)converters.add(fastConverter)} }
数据源配置
com.zaxxer.hikari.HikariConfigcom.zaxxer.hikari.HikariDataSourceorg.springframework.beans.factory.annotation.org.springframework.context.annotation.org.springframework.context.annotation.org.springframework.context.annotation.org.springframework.jdbc.datasource.DataSourceTransactionManagerorg.springframework.transaction.PlatformTransactionManagerorg.springframework.transaction.annotation.javax.sql.DataSource({}) DataSourceConfig { () String () String () String () String () () () () () () () () () () (=) DataSource () { HikariConfig config = HikariConfig()config.setDriverClassName()config.setJdbcUrl()config.setUsername()config.setPassword()config.setReadOnly()config.setConnectionTimeout()config.setIdleTimeout()config.setMaxLifetime()config.setMaximumPoolSize()config.setMinimumIdle()config.addDataSourceProperty()config.addDataSourceProperty()config.addDataSourceProperty()config.addDataSourceProperty()HikariDataSource ds = HikariDataSource(config)ds} PlatformTransactionManager (DataSource dataSource) { DataSourceTransactionManager(dataSource)} }
Spring容器相关配置
org.apache.ibatis.annotations.org.apache.ibatis.session.SqlSessionFactoryorg.mybatis.spring.SqlSessionFactoryBeanorg.mybatis.spring.annotation.org.springframework.context.annotation.org.springframework.context.annotation.org.springframework.context.annotation.org.springframework.context.annotation.org.springframework.context.annotation.FilterTypeorg.springframework.context.annotation.org.springframework.core.io.support.PathMatchingResourcePatternResolverorg.springframework.stereotype.org.springframework.web.bind.annotation.javax.sql.DataSource(= { }= { (= FilterType.= { ..}) }) ({ DataSourceConfig.}) (==.) ApplicationContextConfig { SqlSessionFactory (DataSource dataSource) Exception { SqlSessionFactoryBean factory = SqlSessionFactoryBean()factory.setDataSource(dataSource)PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver()factory.setMapperLocations(resolver.getResources())factory.getObject()} }