xml<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<span style="color:#ff0000;"><!-- 自动扫描web包 ,将带有注解的类 纳入spring容器管理 --></span>
<context:component-scan base-package="com.eduoinfo.finances.bank.web"></context:component-scan>
<!-- 引入jdbc配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:jdbc.properties</value>
</list>
</property>
</bean>
<!-- dataSource 配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!-- mybatis文件配置,扫描所有mapper文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml" p:mapperLocations="classpath:com/eduoinfo/finances/bank/web/dao/*.xml" />
<span style="color:#ff0000;"><!-- spring与mybatis整合配置,扫描所有dao --></span>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.eduoinfo.finances.bank.web.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" />
<!-- 对dataSource 数据源进行事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" />
<span style="color:#ff0000;"><!-- 配置使Spring采用CGLIB代理 --></span>
<aop:aspectj-autoproxy proxy-target-class="true" />
<span style="color:#ff0000;"> <!-- 启用对事务注解的支持 --></span>
<tx:annotation-driven transaction-manager="transactionManager" />
<span style="color:#ff0000;"> <!-- Cache配置 --></span>
<cache:annotation-driven cache-manager="cacheManager" />
<bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehCacheManagerFactory" />
</beans>
xml<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.2.xsd">
<!-- 使用注解开发,不用配置controller,需要配置一个组件扫描器 -->
<context:component-scan base-package="com.edu.test.controller"/>
<!--避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置从项目根目录到指定目录一端路径 ,建议指定浅一点的目录-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 文件的后缀名 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd "
version="2.5">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>spring4.root</param-value>
</context-param>
<!-- ================Spring配置开始================ -->
<!-- 设置Spring容器加载所有的配置文件的路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:Spring/applicationContext.xml,classpath:Spring/spring-mybatis.xml</param-value>
</context-param>
<!-- ================Spring配置结束================ -->
<!-- =========================================== filter =========================================== -->
<!-- Spring 字符编码配置 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!--<description>字符集过滤器</description>-->
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!--<description>字符集编码</description>-->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- =========================================== listener =========================================== -->
<!-- 配置Spring监听器,可以在容器启动时,加载contextConfigLocation的context-param节点的配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 监听HTTP请求事件,为Bean的request,session,globalsession等作用域提供支持 -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- =========================================== servlet =========================================== -->
<!-- ================配置SpringMVC核心调度器================ -->
<!-- 不指定具体文件的话,默认为"/WEB-INF/<servlet name>-servlet.xml" -->
<!-- load-on-startup代表启动顺序,设置为大于等于0表示容器在应用启动时就加载并初始化这个servlet -->
<!-- 推荐拦截/,风格优雅 -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:Spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- =========================================== servlet-mapping =========================================== -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 设置session过期时间为60分钟 -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!-- 欢迎页面 -->
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
对于一个 spring 项目,在项目启动的时候需要初始化 spring 的环境,说白了就是执行下面的代码
javaAnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
如果是在非 web 项目中,我们可以在 main 方法中,执行上述的代码; 但是在 web 项目中,由于项目的入口在容器( tomcat ) 中,而 tomcat 启动回去解析 web.xml ,于是 web.xml 中配置一个 ContextLoaderListener, 让容器在启动的时候去初始化 spring 环境
- 拦截请求 - 负责解析 spring-mvc.xml - <load-on-startup>1</load-on-startup> 让容器启动的时候调用该 servlet 的 init 方法
容器( tomcat )启动 -> 加载 web.xml -> 调用 ContextLoaderListener 去 init spring (spring.xml) -> DispatcherServlet 加载 springMVC.xml
在 springBoot 之前,其实就已经可以实现无 xml 了 基于 xml 配置的是原 spring 2 和之前版本的写法。在 spring4 之后,已经提供了无 xml 写法。
SpringWebMVC 官方文档链接 The following example of the Java configuration registers and initializes the DispatcherServlet, which is auto-detected by the Servlet container (see Servlet Config):
javapublic class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletCxt) {
// Load Spring web application configuration
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
// Create and register the DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/app/*");
}
}
java@Configuration
@ComponentScan(basePackages = "com.yui.study")
public class AppConfig {
/* @Bean
public MyService myService() {
return new MyServiceImpl();
}*/
}
javaAnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
javaac.register(AppConfig.class);
java@Configuration
@ComponentScan(basePackages = "com.yui.study") // 扫描注解
public class AppConfig {
// 配置 bean
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
java // 声明 DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(ac);
// 向容器注册 DispatcherServlet
ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
// 设置容器启动时加载该 servlet
registration.setLoadOnStartup(1);
// 拦截请求设置
registration.addMapping("/app/*");
在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。
每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作
java@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
/**
1. webAppInitializerClasses 所有实现 WebApplicationInitializer 的接口,
{@link javax.servlet.annotation.HandlesTypes} 注解表示要拦截个规则
2. servletContext servlet初始化上下文
*/
// WebApplicationInitializer 实例化 list, 由 Class -> Object
List<WebApplicationInitializer> initializers = new LinkedList<>();
if (webAppInitializerClasses != null) {
// 从 webAppInitializerClasses 中获取 WebApplicationInitializer 类型的类
for (Class<?> waiClass : webAppInitializerClasses) {
/*
如果 {waiClass 不是一个接口} 且 {waiClass 不是抽象的} 且 {waiClass 必须是实现 WebApplicationInitializer.class}
WebApplicationInitializer.class.isAssignableFrom(waiClass) 这句是为了防止容器( tomcat 等)实现有问题,传递了非指定类型过来
*/
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
// 实例化 waiClass 并添加到 initializers list 中
initializers.add((WebApplicationInitializer)
ReflectionUtils.accessibleConstructor(waiClass).newInstance());
} catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
}
// 如果 initializers 为空 输出日志,并结束初始化
if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
}
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
/**
对 initializers 进行排序,从小到大排
@see org.springframework.core.OrderComparator#doCompare
继承 Ordered 或者 PriorityOrdered 重写 getOrder 进行排序
排序规则: PriorityOrdered 在 Ordered 前面,同个接口实现,getOrder() 的值越小越排在前面
*/
AnnotationAwareOrderComparator.sort(initializers);
// 调用所有 initializer 的 onStartUp() 方法, 并将 servlet 上下文传递过去
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}
}
Set<Class<?>> webAppInitializerClasses
java所有当前 class 的类注解 @HandlesTypes 的 value 的实现类
gradlecompile("org.apache.tomcat.embed:tomcat-embed-core:8.5.33")
public class MySpringBootApplication { public static void main(String[] args) throws Exception{ Tomcat myTomcat = new Tomcat(); myTomcat.setPort(8090); myTomcat.addWebapp("/","D:\\data\\web"); myTomcat.start(); myTomcat.getServer().await(); /*// Load Spring web application configuration myTomcat.addContext("/","D:\\data\\web"); AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ac.register(AppConfig.class); // ac.refresh(); // Create and register the DispatcherServlet DispatcherServlet servlet = new DispatcherServlet(ac); Wrapper mvc = myTomcat.addServlet("/","app", servlet); mvc.setLoadOnStartup(1); mvc.addMapping("/*"); myTomcat.start(); myTomcat.getServer().await();*/ } }
本文作者:Yui_HTT
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!