1.事务的实现方式
(1) 实现方式共有两种:编码方式;声明式事务管理方式。
(2) 基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
(3) 声明式事务管理又有两种方式:一种是基于XML配置文件的方式;另一种是在业务方法上添加@Transactional注解,将事务规则应用到业务逻辑中(一般定义在service层)。
xml配置文件:
applicationContext-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<!-- AOP Configuration -->
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:advice id="txAdvice2" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<!--<tx:method name="*" propagation="REQUIRED" timeout="1000" /> -->
</tx:attributes>
</tx:advice>
<!-- 表示使用cglib,而非JDK的动态代理,因为Controller没有实现接口,所以要配置这里 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<aop:config>
<!-- 事务 -->
<aop:advisor id="servicesPointcut" advice-ref="txAdvice2"
pointcut="execution(* com.house365.service..*..impl..*(..))" order="2" />
</aop:config>
</beans>
2.dataSource配置
applicationContext-datasource.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<bean id="commonDatasource" abstract="true">
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
<property name="minIdle" value="3"/>
<property name="maxWait" value="60000"/>
<property name="removeAbandoned" value="true"/>
<!--1.如果开启了removeAbandoned,当getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时被触发. -->
<property name="removeAbandonedTimeout" value="180"/>
<!--<property name="logAbandoned" value="true" /> -->
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="validationQuery" value="select 1 from dual"/>
</bean>
<!-- 数据源配置 -->
<bean id="defaultDataSource" class="org.apache.commons.dbcp.BasicDataSource"
parent="commonDatasource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<property name="maxWait" value="${jdbc.maxWait}"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="defaultDataSource"/>
</bean>
<tx:annotation-driven/>
<bean id="commonSqlMapClient" abstract="true">
<property name="configLocations">
<list>
<value>classpath:sqlMapConfig.xml</value>
</list>
</property>
</bean>
<!-- 目前读写不分离,读写使用同一个source -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" parent="commonSqlMapClient">
<property name="dataSource" ref="defaultDataSource"/>
</bean>
</beans>
3.Trigger定时器
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="gwAllTrigger" />
<ref bean="competeBidding" />
<ref bean="notSignTrigger" />
<ref bean="grabCustomerPushTrigger" />
<ref bean="synRevSenMsgTrigger" />
<!-- <ref bean="synNotResponseMsgTrigger" /> -->
<ref bean="synIncScoreMsgTrigger" />
<ref bean="getPreAboutCustomer" />
</list>
</property>
</bean>
<bean id="synIncScoreMsgTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="synIncScoreMsgDetail" />
<property name="cronExpression" value="${synIncScoreMsg.time}" />
</bean>
<bean id="synIncScoreMsgDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="synIncScoreMsg" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>syn</value>
</property>
</bean>
<!-- <bean id="synNotResponseMsgTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="synNotResponseMsgDetail" />
<property name="cronExpression" value="${synNotResponseMsg.time}" />
</bean>
<bean id="synNotResponseMsgDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
调用的类
<property name="targetObject">
<ref bean="synNotResponseMsg" />
</property>
调用类中的方法
<property name="targetMethod">
<value>syn</value>
</property>
</bean> -->
<bean id="synRevSenMsgTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="synRevSenMsgDetail" />
<property name="cronExpression" value="${synRevSenMsg.time}" />
</bean>
<bean id="synRevSenMsgDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="synRevSenMsg" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>syn</value>
</property>
</bean>
<!-- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers"> <list> <ref bean="zfAllTrigger" /> </list> </property>
</bean> -->
<bean id="gwAllTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dzAllQuote" />
<property name="cronExpression" value="${hmc.start.time}" />
</bean>
<!-- <bean id="zfAllTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="zfAllQuote" /> <property name="cronExpression"
value="${scf.end.time}" /> </bean> -->
<bean id="dzAllQuote"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="callRecordTimer" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>insertRecord</value>
</property>
</bean>
<!-- <bean id="zfAllQuote" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject"> <ref bean="sendSmsTimer" /> </property> <property
name="targetMethod"> <value>sendBidEndSms</value> </property> </bean> -->
<bean id="competeBidding" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="competeBiddingTimer" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>competeBiddingCompute</value>
</property>
</bean>
</property>
<property name="cronExpression" value="${competebidding.time}" />
</bean>
<!-- 签到推送 add by liuyang -->
<bean id="notSignTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="notSignPushTimer" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>notSignPush</value>
</property>
</bean>
</property>
<property name="cronExpression" value="${notSignPush.time}" />
</bean>
<!-- 抢客推送 add by liuyang -->
<bean id="grabCustomerPushTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="grabCustomerPushTimer" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>grabCustomerPush</value>
</property>
</bean>
</property>
<property name="cronExpression" value="${grabCustomerPush.time}" />
</bean>
<bean id="getPreAboutCustomer" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="preAboutCustomerTimer" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>getPreAboutCustomerTime</value>
</property>
</bean>
</property>
<property name="cronExpression" value="${getPreAboutCustomer.time}" />
</bean>
</beans>
#竞拍开始提醒
bid.start.time = 0 0 / 10 9 - 17 * * ?
#竞拍结束提醒
scf.end.time = 0 0 / 10 9 - 17 * * ?
hmc.start.time = 0 0 7 * * ?
#竞标出价统计时间#
competebidding.time = 30 0 10 * * ?
#竞标出价统计时间##
grabcustomer.time = 0 / 10 * * * * ?
#竞标出价统计时间#
getPreAboutCustomer.time = 0 0 1 * * ?
synRevSenMsg.time = 0 0 2 * * ?
synNotResponseMsg.time = 0 0 2 * * ? 0 * /1 * * * ?
synIncScoreMsg.time = 0 10 9 * * ? #推送未签到 #
notSignPush.time = 0 0 11 * * ? #抢客推送定时#
4.dubbo、zookeeper
<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="${dubbo.application.name}"/>
<!-- 使用multicast广播注册中心暴露服务地址 -->
<!-- 配置dubbo缓存文件路径,不能默认,若默认,多个项目的缓存路径一样,会起冲突 -->
<dubbo:registry protocol="zookeeper" address="${dubbo.zookeeper.address}" client="zkclient"
file="${catalina.home}/dubbo/${dubbo.application.name}.cache"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="${dubbo.application.port}"/>
<!-- 不检查服务是否有provider,待provider启动后,会被cousumer自动发现 -->
<dubbo:consumer check="false" retries="0" timeout="5000" version="${dubbo.app.version}"/>
<!--资讯管理 begin -->
<dubbo:service interface="com.house365.ws.interfaces.server.IHmcInformationInterface" ref="hmcInformationInterface" timeout="10000" version="${dubbo.app.version}"/>
<!--资讯管理 end -->
</beans>
5.message(国际化)
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<!-- 读取messages Properties文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:/messages/common</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
</beans>
在同目录下的/messages/common文件夹中创建:
common_zh_CN.properties(中文)
common.properties(英文)
6.fastdfs 文件服务器
# connect timeout in seconds
# default value is 30s
connect_timeout=30
# network timeout in seconds
# default value is 30s
network_timeout=60
# the base path to store log files
base_path=/
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
#tracker_server=192.168.105.101:22122
#tracker_server local ip
tracker_server=172.17.1.98:22122
tracker_server=172.17.1.69:22122
#tracker_server global ip
#tracker_server=202.102.83.154:22122
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=error
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = true
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false
# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false
# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf
#HTTP settings
http.tracker_server_port=80
#use "#include" directive to include HTTP other settiongs
##include http.conf
7.Servlet
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!-- 自动扫描的包名 -->
<context:component-scan base-package="com.house365.web.controller" />
<!-- 使用默认的Servlet来响应静态文件。 -->
<!-- DispatcherServlet把找不到的请求映射到默认的servlet,从而实现处理静态资源的请求 -->
<mvc:default-servlet-handler/>
<!-- 添加注解驱动 -->
<mvc:annotation-driven />
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 防止重复提交,请在页面添加"<house365:token/>" -->
<!--
<bean class="com.house365.web.system.interceptor.DenyDuplicateFormSubmitInterceptor" />
-->
<bean class="com.house365.web.interceptor.CommonParamsInterceptor" />
<bean class="com.house365.web.interceptor.UserTokenInterceptor" />
</mvc:interceptors>
<!-- 配置国际化拦截器 -->
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="requestMappingHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!-- 默认的controller
<mvc:view-controller path="/" view-name="index" /> -->
<!-- 配置视图解析器 -->
<bean id="jstlViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="order" value="1" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<context:property-placeholder ignore-unresolvable="true" location="classpath*:/properties/*.properties" />
<!-- 创建一个通用的多部分解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8" />
<property name="maxUploadSize" value="20480000" />
</bean>
</beans>
8.日志
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- 输出到日志文件(其他部分的日志) -->
<!-- 每天产生一个日志文件 -->
<appender name="app_filelog" class="org.apache.log4j.DailyRollingFileAppender">
<!-- 设置File参数:日志输出文件名 -->
<param name="File" value="${catalina.home}/logs/house365-web.log"/>
<!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="Append" value="true"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<!-- 设置输出文件项目和格式 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %-d{yyyy-MM-dd HH:mm:ss} [%c.%M(%L)] - %m%n"/>
</layout>
</appender>
<!-- 输出到控制台中 -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: [%c.(%L)%M] - %m%n"/>
</layout>
</appender>
<!-- 设置包限制输出的通道(springframework -->
<logger name="org.springframework" additivity="false">
<level value="ERROR"/>
<appender-ref ref="console"/>
<appender-ref ref="app_filelog"/>
</logger>
<!-- 设置类名限制输出的通道(Connection) -->
<logger name="java.sql.Connection" additivity="false">
<level value="ERROR"/>
<appender-ref ref="console"/>
<appender-ref ref="app_filelog"/>
</logger>
<!-- 设置类名限制输出的通道(Statement) -->
<logger name="java.sql.Statement" additivity="false">
<level value="ERROR"/>
<appender-ref ref="console"/>
<appender-ref ref="app_filelog"/>
</logger>
<!-- 设置类名限制输出的通道(PreparedStatement) -->
<logger name="java.sql.PreparedStatement" additivity="false">
<level value="ERROR"/>
<appender-ref ref="console"/>
<appender-ref ref="app_filelog"/>
</logger>
<!-- 设置类名限制输出的通道(ResultSet) -->
<logger name="java.sql.ResultSet" additivity="false">
<level value="ERROR"/>
<appender-ref ref="console"/>
<appender-ref ref="app_filelog"/>
</logger>
<!-- 设置接收所有输出的通道 -->
<root>
<level value="WARN"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
网友评论