spring配置,事务,注解

来源:互联网 发布:重庆西南大学网络学费 编辑:程序博客网 时间:2024/06/05 04:50
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  3.     xmlns="http://xmlns.jcp.org/xml/ns/javaee"    
  4.     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"    
  5.     id="WebApp_ID" version="3.1">     
  6.        
  7.     <display-name>ws</display-name>    
  8.     
  9.     <!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码 -->  
  10.     <filter>  
  11.         <filter-name>CharacterEncodingFilter</filter-name>  
  12.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  13.         <init-param>  
  14.             <param-name>encoding</param-name>  
  15.             <param-value>UTF-8</param-value>  
  16.         </init-param>  
  17.         <init-param>  
  18.             <param-name>forceEncoding</param-name>  
  19.             <param-value>true</param-value>  
  20.         </init-param>  
  21.     </filter>  
  22.     <filter-mapping>  
  23.         <filter-name>CharacterEncodingFilter</filter-name>  
  24.         <url-pattern>/*</url-pattern>  
  25.     </filter-mapping>  
  26.       
  27.     <!-- 指定spring配置文件位置 -->  
  28.     <context-param>  
  29.         <param-name>contextConfigLocation</param-name>  
  30.         <param-value>classpath*:/spring/spring-context*.xml</param-value>  
  31.     </context-param>  
  32.       
  33.     <!-- Spring ApplicationContext 载入,可以继承此接口进行扩展 -->  
  34.     <listener>  
  35.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  36.     </listener>  
  37.       
  38.     <!-- Spring 刷新Introspector防止内存泄露 -->    
  39.     <listener>    
  40.         <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>    
  41.     </listener>   
  42.        
  43.     <!-- 使spring支持request、session及globalsession的作用域 -->  
  44.     <listener>  
  45.         <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>    
  46.     </listener>  
  47.           
  48.     <!-- SpringMVC核心分发器 -->  
  49.     <servlet>  
  50.         <servlet-name>springServlet</servlet-name>  
  51.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  52.         <init-param>  
  53.             <param-name>contextConfigLocation</param-name>  
  54.             <param-value>classpath*:/spring/spring-mvc*.xml</param-value>  
  55.         </init-param>  
  56.         <!-- 取消其自动注册的异常解析器 -->  
  57.         <init-param>  
  58.             <param-name>detectAllHandlerExceptionResolvers</param-name>  
  59.             <param-value>false</param-value>  
  60.         </init-param>  
  61.         <load-on-startup>1</load-on-startup>  
  62.     </servlet>  
  63.     <servlet-mapping>  
  64.         <servlet-name>springServlet</servlet-name>  
  65.         <url-pattern>/*</url-pattern>  
  66.     </servlet-mapping>  
  67.       
  68.     <!--===============================================shiro过虑器================================================-->    
  69.     <!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->  
  70.     <filter>    
  71.         <filter-name>shiroFilter</filter-name>    
  72.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  73.         <init-param>  
  74.             <!-- 设置true由servlet容器控制filter的生命周期 -->  
  75.             <param-name>targetFilterLifecycle</param-name>  
  76.             <param-value>true</param-value>  
  77.         </init-param>  
  78.         <!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->  
  79.         <init-param>  
  80.             <param-name>targetBeanName</param-name>  
  81.             <param-value>shiroFilter</param-value>  
  82.         </init-param>  
  83.     </filter>  
  84.     <filter-mapping>  
  85.         <filter-name>shiroFilter</filter-name>  
  86.         <url-pattern>/*</url-pattern>  
  87.     </filter-mapping>  
  88.       
  89.     <!-- gzip filter    
  90.     <filter>  
  91.         <filter-name>GZIPFilter</filter-name>  
  92.         <filter-class>com.ydkj.ws.common.filter.GZIPFilter</filter-class>  
  93.     </filter>  
  94.     <filter-mapping>  
  95.         <filter-name>GZIPFilter</filter-name>  
  96.         <url-pattern>/*</url-pattern>  
  97.     </filter-mapping>  
  98.     -->  
  99.       
  100.     <!-- etag filter -->  
  101. <!--     <filter> -->  
  102. <!--         <filter-name>etagFilter</filter-name> -->  
  103. <!--         <filter-class>com.ydkj.ws.common.filter.EtagHeaderFilter</filter-class> -->  
  104. <!--         <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class> -->  
  105. <!--     </filter> -->  
  106.       
  107.     <!-- 错误页面 -->  
  108.     <error-page>  
  109.         <error-code>400</error-code>  
  110.         <location>/WEB-INF/views/400.html</location>  
  111.     </error-page>  
  112.     <error-page>  
  113.         <error-code>403</error-code>  
  114.         <location>/WEB-INF/views/403.html</location>  
  115.     </error-page>  
  116.     <error-page>  
  117.         <error-code>404</error-code>  
  118.         <location>/WEB-INF/views/404.html</location>  
  119.     </error-page>  
  120.     <error-page>  
  121.         <error-code>500</error-code>  
  122.         <location>/WEB-INF/views/500.html</location>  
  123.     </error-page>  
  124. </web-app>    
,其次是spring-context.xml文件,

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:aop="http://www.springframework.org/schema/aop"  
  5.     xmlns:context="http://www.springframework.org/schema/context"   
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xmlns:jpa="http://www.springframework.org/schema/data/jpa"  
  8.     xmlns:security="http://www.springframework.org/schema/security"  
  9.     xsi:schemaLocation="  
  10.         http://www.springframework.org/schema/aop   
  11.         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
  12.         http://www.springframework.org/schema/security   
  13.         http://www.springframework.org/schema/security/spring-security-3.2.xsd  
  14.         http://www.springframework.org/schema/beans   
  15.         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
  16.         http://www.springframework.org/schema/data/jpa   
  17.         http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd  
  18.         http://www.springframework.org/schema/tx   
  19.         http://www.springframework.org/schema/tx/spring-tx-4.0.xsd  
  20.         http://www.springframework.org/schema/context   
  21.         http://www.springframework.org/schema/context/spring-context-4.0.xsd">  
  22.     <description>Spring Configuration</description>  
  23.       
  24.      <!-- 使用Annotation自动注册Bean,解决事务失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  -->  
  25.      <context:component-scan base-package="com.ydkj">  
  26.          <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
  27.      </context:component-scan>  
  28.       
  29.     <!-- 加载配置属性文件 -->  
  30.     <context:property-placeholder ignore-unresolvable="true" location="classpath*:properties/webview.properties" />  
  31.     <context:property-placeholder ignore-unresolvable="true" location="classpath*:properties/base_config.properties" />  
  32.     <context:property-placeholder ignore-unresolvable="true" location="classpath*:properties/redis.properties" />  
  33.       
  34.     <!-- 数据库连接、用户名、密码加密处理 -->  
  35.     <bean id="propertyConfigurer" class="com.ydkj.ws.config.EncryptPropertyPlaceholderConfigurer">  
  36.         <property name="locations">  
  37.             <list>  
  38.                 <value>classpath*:jdbc.properties</value>  
  39.             </list>  
  40.         </property>  
  41.         <!-- 加密的属性字段集合 -->  
  42.         <property name="encryptedProps">  
  43.             <set>  
  44.                 <value>jdbc.url</value>  
  45.                 <value>jdbc.username</value>  
  46.                 <value>jdbc.password</value>  
  47.             </set>  
  48.         </property>  
  49.     </bean>  
  50.       
  51.     <!-- 数据源配置, 使用 Druid 数据库连接池 -->  
  52.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   
  53.         <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->  
  54.         <property name="driverClassName" value="${jdbc.driver}" />  
  55.           
  56.         <!-- 基本属性 url、user、password -->  
  57.         <property name="url" value="${jdbc.url}" />  
  58.         <property name="username" value="${jdbc.username}" />  
  59.         <property name="password" value="${jdbc.password}" />  
  60.           
  61.         <!-- 配置初始化大小、最小、最大 -->  
  62.         <property name="initialSize" value="${jdbc.pool.init}" />  
  63.         <property name="minIdle" value="${jdbc.pool.minIdle}" />   
  64.         <property name="maxActive" value="${jdbc.pool.maxActive}" />  
  65.           
  66.         <!-- 配置获取连接等待超时的时间 -->  
  67.         <property name="maxWait" value="60000" />  
  68.           
  69.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  70.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  71.           
  72.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  73.         <property name="minEvictableIdleTimeMillis" value="300000" />  
  74.           
  75.         <property name="validationQuery" value="${jdbc.testSql}" />  
  76.         <property name="testWhileIdle" value="true" />  
  77.         <property name="testOnBorrow" value="false" />  
  78.         <property name="testOnReturn" value="false" />  
  79.           
  80.         <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)  
  81.         <property name="poolPreparedStatements" value="true" />  
  82.         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->  
  83.           
  84.         <!-- 配置监控统计拦截的filters -->  
  85.         <property name="filters" value="stat" />   
  86.     </bean>  
  87.       
  88.     <bean id="myP6DataSource" class="com.p6spy.engine.spy.P6DataSource">  
  89.         <constructor-arg>  
  90.             <ref bean="dataSource"/>  
  91.         </constructor-arg>  
  92.     </bean>  
  93.       
  94.     <!-- Mybatis配置 -->  
  95.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  96.         <property name="dataSource" ref="myP6DataSource" />  
  97.         <property name="typeAliasesPackage" value="com.ydkj" />  
  98.         <property name="mapperLocations" value="classpath:/mappings/**/*.xml" />  
  99.         <property name="configLocation" value="classpath:/mybatis-config.xml" />  
  100.     </bean>  
  101.       
  102.     <!-- 扫描basePackage下所有以 @MyBatisDao注解的接口注解的接口 -->  
  103.     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
  104.         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />  
  105.         <property name="basePackage" value="com.ydkj"/>  
  106.         <property name="annotationClass" value="com.ydkj.common.persistence.annotation.MyBatisDao" />  
  107.     </bean>  
  108.           
  109.     <!-- 配置SQLSession模板 -->  
  110.     <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">  
  111.         <constructor-arg index="0" ref="sqlSessionFactory" />  
  112.     </bean>  
  113.       
  114.     <!-- 声明式事务管理 -->  
  115.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  116.         <property name="dataSource" ref="dataSource" />  
  117.     </bean>  
  118.       
  119.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  120.         <tx:attributes>  
  121.             <tx:method name="get*" read-only="true"  propagation="SUPPORTS"/>  
  122.             <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>  
  123.             <tx:method name="select*" read-only="true" propagation="SUPPORTS"/>  
  124.             <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>  
  125.             <!-- 开启新事务  -->  
  126.             <tx:method name="error*" propagation="REQUIRES_NEW"/>  
  127.             <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />  
  128.         </tx:attributes>  
  129.     </tx:advice>  
  130.       
  131.     <aop:config>  
  132.         <aop:pointcut id="transactionPointcut" expression="execution(* *..*ServiceImpl.*(..))||execution(* com.ydkj.*.service.*.*(..))||execution(* com.ydkj.*.*.service.*.*(..))"/>  
  133.         <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>  
  134.     </aop:config>  
  135.       
  136. <!--     <aop:aspectj-autoproxy proxy-target-class="true"/> -->  
  137.     <!-- 使用annotation注解方式配置事务 -->  
  138.     <tx:annotation-driven transaction-manager="transactionManager" />  
  139.       
  140.     <!-- spring data redis -->  
  141.     <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
  142.         <property name="hostName" value="${redis.host}" />  
  143.         <property name="port" value="${redis.port}" />  
  144.         <property name="password" value="${redis.pass}" />  
  145.         <property name="timeout" value="10000" />  
  146.     </bean>  
  147.   
  148.     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
  149.         <property name="connectionFactory" ref="jedisConnectionFactory" />  
  150.         <!-- 如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast   
  151.             to String!!! -->  
  152.         <property name="keySerializer">  
  153.             <bean  
  154.                 class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  155.         </property>  
  156.         <property name="valueSerializer">  
  157.             <bean  
  158.                 class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />  
  159.         </property>  
  160.         <property name="hashKeySerializer">  
  161.             <bean  
  162.                 class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  163.         </property>  
  164.         <property name="hashValueSerializer">  
  165.             <bean  
  166.                 class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />  
  167.         </property>  
  168.     </bean>  
  169.       
  170.     <import resource="classpath*:spring-context-shiro.xml"/>  
  171. </beans>  

再就是springmvc配置文件,spring-mvc.xml,

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:mvc="http://www.springframework.org/schema/mvc"   
  5.     xmlns:p="http://www.springframework.org/schema/p"   
  6.     xmlns:context="http://www.springframework.org/schema/context"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  8.     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
  9.     http://www.springframework.org/schema/context   
  10.     http://www.springframework.org/schema/context/spring-context-4.0.xsd  
  11.     http://www.springframework.org/schema/mvc    
  12.     http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
  13.       
  14.      <!-- 使用Annotation自动注册Bean,只扫描@Controller -->  
  15.      <context:component-scan base-package="com.ydkj" use-default-filters="false">    
  16.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    
  17.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>    
  18.      </context:component-scan>    
  19.       
  20.     <mvc:interceptors>    
  21.         <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->    
  22.         <bean class="com.ydkj.ws.Interceptor.SpringMVCInterceptor"/>    
  23.         <mvc:interceptor>    
  24.             <mvc:mapping path="/**"/>    
  25.             <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->    
  26.             <bean class="com.ydkj.ws.Interceptor.SpringMVCInterceptor"/>    
  27.         </mvc:interceptor>    
  28.     </mvc:interceptors>    
  29.   
  30.     <!--Spring3.1开始的注解 HandlerMapping -->  
  31.     <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />  
  32.     <!--Spring3.1开始的注解 HandlerAdapter -->  
  33.     <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />  
  34.   
  35.     <!-- 视图解释类 -->  
  36.     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  37.         <property name="prefix" value="${web.view.prefix}" />  
  38.         <property name="suffix" value="${web.view.suffix}" />  
  39.         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />  
  40.     </bean>  
  41.       
  42.     <!-- 定义无Controller的path<->view直接映射 -->  
  43.     <mvc:view-controller path="/ws" view-name="redirect:${web.view.index}"/>  
  44.       
  45.     <!-- 对静态资源文件的访问, 将无法mapping到Controller的path交给default servlet handler处理 -->  
  46.     <mvc:default-servlet-handler />  
  47.       
  48.     <!-- 配置swagger展示页面 -->  
  49.     <bean class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration" id="swagger2Config"/>    
  50.     <mvc:annotation-driven/><!-- 默认的注解映射的支持 -->    
  51.     <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>  
  52.     <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>  
  53.     <bean class="com.ydkj.ws.common.swagger.SpringfoxDocConfig"></bean>  
  54. </beans>  
排除方法依次是检查mysql数据库表类型,确认为innodb,支持事务。

确认包扫描时顺序,spring不扫描controller,springmvc扫描controller,父子容器的关系,有一篇文章介绍。

http://blog.csdn.net/yeluosc/article/details/35650501
排除了这两个问题后,又定位web容器加载顺序,确认先加载spring,再加载springmvc。

到这里看不出问题了。

这个项目是参考一个SSH架构的项目做的,关于SSH架构的项目配置,参考我的另外一篇博文。


症结所在:com.p6spy.engine.spy.P6DataSource的使用不当导致。

hibernate有自己事务的实现

[html] view plain copy
  1. <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"  
  2.       abstract="false" lazy-init="default" autowire="default">  
  3.     <property name="sessionFactory" ref="sessionFactory"/>  
  4. </bean>  

这个时候给事务注入sqlFactory,而sqlFactory定义的dataSource是myP6DataSource。


而mybatis没有sqlFactory,只有sqlSessionFactory,我的配置文件里sqlSessionFactory定义的dataSource是 myP6DataSource,正好配置的transactionManager没有使用myP6DataSource,而是直接配置的dataSource。如果改成下面的配置,则问题早就解决了。

<property name="dataSource" ref="myP6DataSource" />