声明式事务

环境搭建

  1. 导入相关依赖

    • 数据源
    • 数据库驱动
    • spring-jdbc模块
  2. 配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @EnableTransactionManagement	//开启基于注解的事务管理功能
    @ComponentScan("com.wxs.tx")
    @Configuration
    public class TxConfig {

    //配置数据源
    @Bean
    public DataSource dataSource() throws PropertyVetoException {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setUser("root");
    dataSource.setPassword("abc123aa");
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
    //Spring 对 Configuration 类会特殊处理,多次调用给容器中加组件的方法都是从容器中找组件
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
    return jdbcTemplate;
    }

    }
  3. 给方法标注上 @Transactional 注解

  4. @EnableTransactionManagement 开启基于注解的事务管理功能

  5. 配置事务管理器来控制事务

    1
    2
    3
    4
    5
    6
    //事务管理器
    @Bean
    public PlatformTransactionManager transactionManager()
    throws PropertyVetoException {
    return new DataSourceTransactionManager(dataSource());
    }

简单测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Repository
public class UserDao {

@Autowired
private JdbcTemplate jdbcTemplate;

/*添加事务注解
如果整个方法正常执行,则方法正常提交
如果执行方法期间出现异常,所有的方法都回滚
*/
@Transactional
public void insert() {
String sql = "INSERT INTO `tbl_user` (username,age) VALUES (?,?)";
String username = UUID.randomUUID().toString().substring(0, 5);
jdbcTemplate.update(sql, username, 20);
//测试假装方法中出现了错误
int num = 1 / 0
}
}
1
2
3
4
5
6
7
8
9
10
11
@Service
public class UserService {

@Autowired
UserDao userDao;

public void insert() {
userDao.insert();
System.out.println("插入完成!!!");
}
}

Servlet 3.0

基于注解的Servlet(原生的servlet用的比较少):

1
2
3
4
5
6
7
8
9
//拦截 /hello 下的请求,进入doGet()方法执行相应操作
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Hello!");
}
}
1
2
3
<html>
<a href="hello"></a>
</html>

Shared libraries / runtime pluggability

容器在启动应用时,会扫描当前应用每一个jar包里面

META-INF/services/javax.servlet.ServletContainerInitializer

指定的实现类,启动并运行这个实现类的方法

SpringMVC

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* Web容器启动的时候创建对象,调用方法来初始化容器以前的前端控制器
*/
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

//获取根容器的配置类(Spring配置文件) 父容器
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}

//获取web容器的配置类(SpringMVC配置文件) 子容器
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AppConfig.class};
}

//获取DispatcherServlet的映射信息
@Override
protected String[] getServletMappings() {
/**
* /: 拦截所有请求,包括静态资源,不包括 *.jsp
* /*:拦截所有请求包括 *.jsp
* jsp页面是 tomcat 的jsp引擎解析的
*/
return new String[]{"/"};
}
}
1
2
3
4
5
6
7
8
9
/**
* Spring 不扫描 Controller 的容器
* 父容器
*/
@ComponentScan(value = "com.wxs",excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
})
public class RootConfig {
}
1
2
3
4
5
6
7
8
9
10
/**
* SpringMVC 只扫描 Controller
* 子容器
* useDefaultFilters = false:禁用默认的过滤规则
*/
@ComponentScan(value = "com.wxs",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false)
public class AppConfig {
}
1
2
3
4
5
6
7
@Service
public class HelloService {

public String sayHello(String name) {
return "hello" + name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
@Controller
public class HelloController {

@Autowired
HelloService helloService;

@RequestMapping("/hello")
@ResponseBody
public String hello() {
helloService.sayHello("wxs");
return "success";
}
}

定制SpringMVC

  1. @EnableWebMvc:开启SpringMVC定制配置功能
  2. 继承类 WebMvcConfigurer
image-20200420211527677