文章目录
3. 基于 Spring 托管 Service 实现类
3.1 使用 Spring 托管 Service 依赖理论
3.2 使用 Spring 托管 Service 依赖配置
4. 配置并使用 Spring 声明式事务
resources > spring > spring-service.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫描 service 包下所有使用注解的类型 然后在 SeckillServiceImpl 中写注解-->
<context:component-scan base-package="org.seckill.service"/>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置基于注解的声明式事务
默认使用注解来管理事务行为
-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
5. 使用集成测试 Service 逻辑
快捷键ctrl + shift + t
SeckillServiceTest
package org.seckill.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.seckill.dto.Exposer;
import org.seckill.dto.SeckillExecution;
import org.seckill.entity.Seckill;
import org.seckill.exception.RepeatKillException;
import org.seckill.exception.SeckillCloseException;
import org.seckill.exception.SeckillException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath:spring/spring-dao.xml",
"classpath:spring/spring-service.xml"})
public class SeckillServiceTest {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private SeckillService seckillService;
@Test
public void testGetSeckillList() throws Exception {
List<Seckill> list = seckillService.getSeckillList();
logger.info("list={}", list);
}
// Closing non transactional SqlSession
@Test
public void testGetById() throws Exception {
long id = 1000;
Seckill seckill = seckillService.getById(id);
logger.info("seckill={}", seckill);
}
// 测试代码完整逻辑,注意可重复执行。
@Test
public void testSeckillLogic() throws Exception {
long id = 1000;
Exposer exposer = seckillService.exportSeckillUrl(id);
if(exposer.isExposed()) {
logger.info("exposer={}", exposer);
long userPhone = 18742519888L;
String md5 = exposer.getMd5();
try {
SeckillExecution execution = seckillService.executeSeckill(id, userPhone, md5);
logger.info("result={}", execution);
} catch (RepeatKillException e) {
logger.error(e.getMessage());
} catch (SeckillCloseException e) {
logger.error(e.getMessage());
}
} else {
// 秒杀未开启
logger.warn("exposer={}", exposer);
}
}
}
logback.xml
logback 文档:https://logback.qos.ch/manual/configuration.html
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>