一、web.xml文件
<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 修改Spring配置文件的路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<!-- 配置Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--下面这个配置可选-->
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<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>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置druid 拦截 -->
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!--配置spring-mvc-->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet对应的上下文配置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--spring-mvc 拦截mapping-->
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<!--特别提醒,请不要将以下 [/] 写成 [/*] ,会出现找不到mapping的错误-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--和hibernate集合-->
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<!--指定org.springframework.orm.hibernate3.LocalSessionFactoryBean在spring配置文件中的
名称,默认值为sessionFactory。如果LocalSessionFactoryBean在spring中的名称不是
sessionFactory,该参数一定要指定,否则会出现找不到sessionFactory的例外。
所以默认可以不写-->
<init-param>
<param-name>sessionFactoryBean</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app></span>
配置org.springframework.web.context.request.RequestContextListener:
是为了使Spring支持request与session的scope,如:
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前 HTTP request内有效,配置实例: request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:如果使用的是Servlet2.4及以上的web容器,那么需要在web应用的XML声明文件 web.xml中增加这个listener。
配置了上述这个listener之后,还能用于在SpringMVC中获取request对象。配置之后,在程序里可以用:
HttpServletRequest request =
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
不过为了获取request对象,更简单的方式是用注解法:
@Autowired
private HttpServletRequest request;
或更直接的方法是:
public String hello(HttpServletRequest request,HttpServletResponse response)
配置org.springframework.web.filter.CharacterEncodingFilter:
配置org.springframework.orm.hibernate4.support.OpenSessionInViewFilter:
Spring 为我们提供了一个叫做 OpenSessionInViewFilter 的过滤器,他是标准的 Servlet Filter 所以我们把它按照规范配置到 web.xml 中方可使用。使用中我们必须配合使用 Spring 的 HibernateDaoSupport 来进行开发,也就是说,我们的dao层的类都要继承于 HibernateDaoSupport,从中由 Spring 来控制 Hibernate 的 Session 在请求来的时候开启,走的时候关闭,保证了我们访问数据对象时的稳定性。OpenSessionInViewFilter的主要功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。在项目中使用Spring+Hibernate的时候,会开启OpenSessionInViewFilter来阻止延迟加载的错误,但是在我们开启OpenSessionInViewFilter这个过滤器的时候FlushMode就已经被默认设置为了MANUAL,如果FlushMode是MANUAL或NEVEL,在操作过程中 hibernate会将事务设置为readonly,所以在增加、删除或修改操作过程中要将flushMode设置为AUTO。
如果使用了OpenSessionInView模式,那么Spring会帮助你管理Session的开和关,从而你在你的DAO中通过HibernateDaoSupport拿到的getSession()方法,都是绑定到当前线程的线程安全的Session,即拿即用,最后会由Filter统一关闭。但由于拿到的Hibernate的Session被设置了session.setFlushMode(FlushMode.NEVER); 所以,除非直接调用session.flush(),否则Hibernate session无论何时也不会flush任何的状态变化到数据库。因此,数据库事务的配置非常重要。(我们知道,在调用org.hibernate.Transaction.commit()的时候会触发session.flush())我曾经见过很多人在使用OpenSessionInView模式时,都因为没有正确配置事务,导致了底层会抛出有关FlushMode.NEVER的异常。
二、applicationContext.xml文件
<span style="font-size:14px;"><?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
">
<!--1、配置数据库相关参数-->
<context:property-placeholder location="classpath:database.properties" ignore-unresolvable="true"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${db.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.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="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
<property name="filters" value="stat" />
</bean>
<!-- 配置SessionFactory,由Spring容器来管理Hibernate -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 配置自动扫描包下的实体,也可使用annotatedClasses属性进行单个实体配置-->
<property name="packagesToScan" value="com.***.entity"></property>
<!-- 配置Hibernate属性 -->
<property name="hibernateProperties">
<props>
<!-- Enable EhCache -->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.query.substitutions">true 1, false 0, yes 'Y', no 'N'</prop>
</props>
</property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--tx:annotation-driven/ 就是支持事务注解的(@Transactional)-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="process*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置参与事务的类或方法 -->
<aop:config>
<aop:pointcut id="allServiceMethod" expression="execution(* com.***.service.*.*.*(..))" />
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
</aop:config>
<!-- 使Spring关注Annotation -->
<context:annotation-config />
<!--用于定时-->
<task:annotation-driven />
<context:component-scan base-package="定时任务类所在的目录"/>
<!-- 让Spring通过自动扫描来查询和管理Bean,除controller -->
<context:component-scan base-package="com..." >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans></span>
三、mvc-dispatcher-servlet.xml配置(名字自定)
<span style="font-family:SimSun;font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--激活注解功能-->
<context:annotation-config/>
<!--DispatcherServlet上下文,只需管理@Controller类型的bean,忽略其他类型的bean,如@Service-->
<context:component-scan base-package="com.***.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!--启用Spring对@Aspect切面配置的支持 (注意需要放在Spring MVC的配置文件中)-->
<context:component-scan base-package="com.***.sys" />
<aop:aspectj-autoproxy proxy-target-class="true"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/content/"
p:suffix=".jsp" />
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<!--扩展了注解驱动,可以将请求参数绑定在控制器参数上-->
<mvc:annotation-driven/>
<!--异常处理-->
<!--class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">-->
<bean id="handlerExceptionResolver"
class="com.***.sys.MyHandlerExceptionResolver">
<property name="exceptionMappings">
<props>
<!--<prop key="com.itimepost.sys.MissingParameterException">redirect:/album/hello</prop>-->
</props>
</property>
</bean>
</beans></span>
四、database.properties
db.driverClassName =com.mysql.jdbc.Driver
db.url = jdbc:mysql://localhost:3306/项目名?useUnicode=true&characterEncoding=UTF-8
db.user = ***
db.password = ***
五、后记
applicationContext.xml 和 dispatch-servlet.xml形成了两个父子关系的上下文。
1) 一个bean如果在两个文件中都被定义了(比如两个文件中都定义了component scan扫描相同的package), spring会在application context和 servlet context中都生成一个实例,他们处于不同的上下文空间中,他们的行为方式是有可能不一样的。
2) 如果在application context和 servlet context中都存在同一个 @Service 的实例, controller(在servlet context中) 通过 @Resource引用时, 会优先选择servlet context中的实例。
不过最好的方法是:在applicationContext和dispatcher-servlet定义的bean最好不要重复, dispatcher-servlet最好只是定义controller类型的bean。
applicationContext.xml 是spring 全局配置文件,用来控制spring 特性。
dispatcher-servlet.xml 是spring mvc里面的,控制器、拦截uri转发view。