目录
1. SpringBoot从classpath/static的目录... 9
Spring Boot第三章 SpringBoot热部署... 1
1 SpringLoader与DevTools的区别:... 8
2 修改项目的pom文件添加devtools的依赖... 8
SpringBoot第四章(SpringBoot整合SpringMVC+MyBatis)... 1
2 添加application.properties全局配置文件... 3
1 在mapper接口中以及映射配置文件中添加相关代码... 6
1 SpringBoot中对于异常处理提供了五种处理方式... 1
二、 Spring Boot整合Junit单元测试... 8
二、 Spring Boot 整合 Quartz定时任务框架... 5
3 .Spring Boot整合Quartz定时框架... 8
Spring Boot第一章
l Spring Boot介绍
l 构建Spring Boot项目及启动器讲解
l Spring Boot入门HelloWorld
一,Spring Boot 介绍
1,如果使用Spring开发一个"HelloWorld"的web应用:
• 创建一个web项目并且导入相关jar包。SpringMVC Servlet
• 创建一个web.xml
• 编写一个控制类(Controller)
• 需要一个部署web应用的服务器 如tomcat
2,Spring Boot特点:
• Spring Boot设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
• 嵌入的 Tomcat,无需部署 WAR 文件
• Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方式。
二,构建Spring Boot项目及启动器讲解
1.使用maven构建SpringBoot项目
2.修改pom文件 将jdk的版本更新为1.7
3.注入SpringBoot启动坐标
<!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> |
4.SpringBoot启动器。
所谓的springBoot启动器其实就是一些jar包的集合。SprigBoot一共提供44启动器。
4.1 spring-boot-starter-web
支持全栈式的web开发,包括了romcat和springMVC等jar
4.2 spring-boot-starter-jdbc
支持spring以jdbc方式操作数据库的jar包的集合
4.3 spring-boot-starter-redis
支持redis键值存储的数据库操作
三,Spring Boot入门HelloWorld
1.编写返回HelloWorld的Controller
/** * SpringBoot HelloWorld * @author Administrator * */ @Controller public class HelloWorld { @RequestMapping("/hello") @ResponseBody public Map<String, Object> showHelloWorld(){ Map<String, Object> map = new HashMap<>(); map.put("msg", "HelloWorld"); return map; } } |
2.启动SpringBoot 编写启动类
3.关于编写启动器需要注意的问题
启动器存放的位置。启动器可以和controller位于同一个包下,或者位于controller的上一级包中,但是不能放到controller的平级以及子包下。
/** * SpringBoot 启动类 * @author Administrator * */ @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
Spring Boot第二章
l 整合Servlet
l 整合Filter
l 整合Listener
l 访问静态资源
l 文件上传
一,整合Servlet
1,通过注解扫描完成Servlet组件的注册
1.1编写servlet
/** *SpringBoot整合Servlet方式一 * *<servlet> * <servlet-name>FirstServlet</servlet-name> * <servlet-class>com.bjsxt.servlet.FirstServlet</servlet-class> *</servlet> * *<servlet-mapping> * <servlet-name>FirstServlet</servlet-name> * <url-pattern>/first</url-pattern> *</servlet-mapping> * */ @WebServlet(name="FirstServlet",urlPatterns="/first") public class FirstServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } } |
1.2编写启动类
/** * SpringBoot整合Servlet方式一 * * */ @SpringBootApplication @ServletComponentScan //在springBoot启动时会扫描@WebServlet,并将该类实例化 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
2,通过方法完成Servlet组件的注册
2.1编写servlet
/** *SpringBoot整合Servlet方式二 * */ public class SecondServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("SecondServlet.........."); } } |
2.2编写启动类
/** * SpringBoot整合Servlet方式二 * * */ @SpringBootApplication public class App2 { public static void main(String[] args) { SpringApplication.run(App2.class, args); }
@Bean public ServletRegistrationBean getServletRegistrationBean(){ ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet()); bean.addUrlMappings("/second"); return bean; } } |
二,整合Filter
1,通过注解扫描完成Filter组件的注册
1.1编写Filter
/** *SpringBoot整合Filter 方式一 *<filter> * <filter-name>FirstFilter</filter-name> * <filter-class>com.bjsxt.filter.FirstFilter</filter-class> *</filter> *<filter-mapping> * <filter-name>FirstFilter</filter-name> * <url-pattern>/first</url-pattern> *</filter-mapping> */ //@WebFilter(filterName="FirstFilter",urlPatterns={"*.do","*.jsp"}) @WebFilter(filterName="FirstFilter",urlPatterns="/first") public class FirstFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { System.out.println("进入Filter"); arg2.doFilter(arg0, arg1); System.out.println("离开Filter"); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } } |
1.2编写启动类
/** *SpringBoot整合Filter 方式一 * */ @SpringBootApplication @ServletComponentScan public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
2,通过方法完成Filter组件的注册
2.1编写Filter
/** * *SpringBoot整合Filter 方式二 * */ public class SecondFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { System.out.println("进入SecondFilter"); arg2.doFilter(arg0, arg1); System.out.println("离开SecondFilter"); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } } |
2.2编写启动类
/** * SpringBoot整合Filter方式二 * * */ @SpringBootApplication public class App2 { public static void main(String[] args) { SpringApplication.run(App2.class, args); }
/** * 注册Servlet * @return */ @Bean public ServletRegistrationBean getServletRegistrationBean(){ ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet()); bean.addUrlMappings("/second"); return bean; }
/** * 注册Filter */ @Bean public FilterRegistrationBean getFilterRegistrationBean(){ FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter()); //bean.addUrlPatterns(new String[]{"*.do","*.jsp"}); bean.addUrlPatterns("/second"); return bean; } } |
三,整合Listener
1,通过注解扫描完成Listener组件的注册
1.1编写Listener
/** * springBoot整合Listener * *<listener> * <listener-class>com.bjsxt.listener.FirstListener</listener-class> *</listener> */ @WebListener public class FirstListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("Listener...init......"); } } |
1.2编写启动类
/** * springBoot整合Listener方式一 * * */ @SpringBootApplication @ServletComponentScan public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
2. 通过方法完成Listener组件注册
2.1编写Listener
/** * springBoot整合Listener方式二。 * * */ public class SecondListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("SecondListener..init....."); } } |
2.2编写启动类
/** * SpringBoot整合Listener方式二 * * */ @SpringBootApplication public class App2 { public static void main(String[] args) { SpringApplication.run(App2.class, args); } /** * 注册listener */ @Bean public ServletListenerRegistrationBean<SecondListener> getServletListenerRegistrationBean(){ ServletListenerRegistrationBean<SecondListener> bean= new ServletListenerRegistrationBean<SecondListener>(new SecondListener()); return bean; } } |
四,访问静态资源
1. SpringBoot从classpath/static的目录
注意目录名称必须是static
2. ServletContext根目录下
在src/main/webapp 目录名称必须要webapp
五,文件上传
1. 编写Controller
/** * SpringBoot文件上传 * * */ //@Controller @RestController //表示该类下的方法的返回值会自动做json格式的转换 public class FileUploadController { /* * 处理文件上传 */ @RequestMapping("/fileUploadController") public Map<String, Object> fileUpload(MultipartFile filename)throws Exception{ System.out.println(filename.getOriginalFilename()); filename.transferTo(new File("e:/"+filename.getOriginalFilename())); Map<String, Object> map = new HashMap<>(); map.put("msg", "ok"); return map; } } |
2. 编写启动类
/** * SpringBoot文件上传 * * */ @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
3. 设置上传文件大小的默认值
需要添加一个springBoot的配置文件
application.properties
设置单个上传文件的大小
spring.http.multipart.maxFileSize=200MB
设置一次请求上传文件的总容量
spring.http.multipart.maxRequestSize=200MB
Spring Boot第三章 SpringBoot热部署
(SpringBoot高级)
SprigBoot的热部署方式分为两种
l SpringLoader插件
l DevTools工具
一、 SpringLoader插件的使用
1 创建项目
2 修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>20-spring-boot-springloader</artifactId> <version>0.0.1-SNAPSHOT</version>
<properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties>
<dependencies> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- thymeleaf的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> </project> |
3 创建Controller
/** * SpringBoot----SpringLoader * * */ @Controller public class UsersController { @RequestMapping("/show") public String showPage(){ return "index"; } } |
4 编写页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <span th:text="Hello...."></span> </body> </html> |
5 创建启动类
@SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
6 使用SpringLoader进行项目的热部署
6.1 方式一:以maven插件方式使用SpringLoader
6.1.1 在pom文件中添加插件配置
<!-- springloader插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.5.RELEASE</version> </dependency> </dependencies> </plugin> </plugins> </build> |
6.1.2 使用maven的命令起来启动
spring-boot:run
SpringLoader缺陷:就是Java代码做部署处理。但是对页面无能为力。
6.1.3 注意:这种方式的缺点是Springloader热部署程序是在系统后台以进程的形式来运行。需要手动关闭该进程
7 方式二:在项目中直接使用jar包的方式
7.1 添加springloader的jar包
7.2 启动方式
启动命令:
-javaagent:.\lib\springloaded-1.2.5.RELEASE.jar -noverify
二、 DevTools工具
1 SpringLoader与DevTools的区别:
SpringLoader:SpringLoader在部署项目时使用的是热部署的方式。
DevTools:DevTools在部署项目时使用的是重新部署的方式
2 修改项目的pom文件添加devtools的依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>21-spring-boot-devtools</artifactId> <version>0.0.1-SNAPSHOT</version>
<properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties>
<dependencies> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- thymeleaf的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- DevTools的坐标 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
</project> |
SpringBoot第四章(SpringBoot整合SpringMVC+MyBatis)
需求分析:通过使用SpringBoot+SpringMVC+MyBatis整合实现一个对数据库中的users表的CRUD的操作
一、 创建项目
1 修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>12-spring-boot-springmvc-mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties> <dependencies> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- web启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Mybatis启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- druid数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> </dependencies> </project> |
2 添加application.properties全局配置文件
spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/ssm spring.datasource.username=root spring.datasource.password=root spring.datasource.type=com.alibaba.druid.pool.DruidDataSource mybatis.type-aliases-package=com.bjsxt.pojo |
3 数据库表设计
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
二、 添加用户
1 创建实体类
public class Users { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } |
2 创建mapper接口以及映射配置文件
import com.bjsxt.pojo.Users; public interface UsersMapper { void insertUser(Users users); } |
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.bjsxt.mapper.UsersMapper"> <insert id="insertUser" parameterType="users"> insert into users(name,age) values(#{name},#{age}) </insert> </mapper> |
3 创建业务层
@Service @Transactional public class UsersServiceImpl implements UsersService {
@Autowired private UsersMapper usersMapper;
@Override public void addUser(Users users) { this.usersMapper.insertUser(users); } } |
4 创建Controller
@Controller @RequestMapping("/users") public class UsersController { @Autowired private UsersService usersService;
/** * 页面跳转 */ @RequestMapping("/{page}") public String showPage(@PathVariable String page){ return page; }
/** * 添加用户 */ @RequestMapping("/addUser") public String addUser(Users users){ this.usersService.addUser(users); return "ok"; } } |
5 编写页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>添加用户</title> </head> <body>
<form th:action="@{/users/addUser}" method="post"> 用户姓名:<input type="text" name="name"/><br/> 用户年龄:<input type="text" name="age"/><br/> <input type="submit" value="确定"/><br/> </form> </body> </html> |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>操作提示页面</title> </head> <body> 操作成功!!! </body> </html> |
6 启动类
@SpringBootApplication @MapperScan("com.bjsxt.mapper") //@MapperScan 用户扫描MyBatis的Mapper接口 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
三、 查询用户
1 在mapper接口中以及映射配置文件中添加相关代码
List<Users> selectUsersAll(); |
<select id="selectUsersAll" resultType="users"> select id,name,age from users </select> |
2 在业务层中添加查询方法
@Override public List<Users> findUserAll() { return this.usersMapper.selectUsersAll(); } |
3 在Controller中添加方法
/** * 查询全部用户 */ @RequestMapping("/findUserAll") public String findUserAll(Model model){ List<Users> list = this.usersService.findUserAll(); model.addAttribute("list", list); return "showUsers"; } |
4 添加页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>展示用户数据</title> </head> <body> <table border="1" style="width:300px;"> <tr> <th>用户ID</th> <th>用户姓名</th> <th>用户年龄</th> </tr> <tr th:each="user : ${list}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> </tr> </table> </body> </html> |
四、 用户更新
1 更新用户之前的查询,并将数据在页面中回显
1.1 修改mapper接口以及映射配置文件
Users selectUsersById(Integer id); |
<select id="selectUsersById" resultType="users"> select id,name,age from users where id = #{value} </select> |
1.2 修改业务层代码
@Override public Users findUserById(Integer id) { return this.usersMapper.selectUsersById(id); } |
1.3 修改Controller
/** * 根据用户id查询用户 */ @RequestMapping("/findUserById") public String findUserById(Integer id,Model model){ Users user = this.usersService.findUserById(id); model.addAttribute("user", user); return "updateUser"; } |
1.4 添加页面 updateUsers.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form th:action="@{/users/editUser}" method="post"> <input type="hidden" name="id" th:field="${user.id}"/> 用户姓名:<input type="text" name="name" th:field="${user.name}"/><br/> 用户年龄:<input type="text" name="age" th:field="${user.age}"/><br/> <input type="submit" value="确定"/><br/> </form> </body> </html> |
1.5 修改showUsers.html页面添加操作功能
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>展示用户数据</title> </head> <body> <table border="1" style="width:300px;"> <tr> <th>用户ID</th> <th>用户姓名</th> <th>用户年龄</th> <th>操作</th> </tr> <tr th:each="user : ${list}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td> <a th:href="@{/users/findUserById(id=${user.id})}">更新用户</a> </td> </tr> </table> </body> </html> |
2 用户更新
2.1 修改mapper接口以及映射配置文件
void updateUser(Users users); |
<update id="updateUser" parameterType="users"> update users set name=#{name} ,age=#{age} where id=#{id} </update> |
2.2 修改业务层代码
@Override public void updateUser(Users users) { this.usersMapper.updateUser(users); } |
2.3 修改Controller
/** * 更新用户 */ @RequestMapping("/editUser") public String editUser(Users users){ this.usersService.updateUser(users); return "ok"; }
|
五、 删除用户
1 修改mapper接口以及映射配置文件
void deleteUserById(Integer id); |
<delete id="deleteUserById"> delete from users where id = #{value} </delete> |
2 修改业务层代码
@Override public void deleteUserById(Integer id) { this.usersMapper.deleteUserById(id); } |
3 修改Controller
/** * 删除用户 */ @RequestMapping("/delUser") public String delUser(Integer id){ this.usersService.deleteUserById(id); return "redirect:/users/findUserAll"; } |
4 修改showUsers.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>展示用户数据</title> </head> <body> <table border="1" style="width:300px;"> <tr> <th>用户ID</th> <th>用户姓名</th> <th>用户年龄</th> <th>操作</th> </tr> <tr th:each="user : ${list}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td> <a th:href="@{/users/findUserById(id=${user.id})}">更新用户</a> <a th:href="@{/users/delUser(id=${user.id})}">删除用户</a> </td> </tr> </table> </body> </html> |
第六章节Spring Boot定时任务
(SpringBoot高级)
l Scheduled定时任务器
l 整合Quartz定时任务框架
一、 Scheduled定时任务器
Scheduled定时任务器:是Spring3.0以后自带的一个定时任务器。
1 在pom文件中添加Scheduled的坐标
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>25-spring-boot-scheduled</artifactId> <version>0.0.1-SNAPSHOT</version>
<properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties>
<dependencies> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 添加Scheduled坐标 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> </dependencies> </project> |
2 编写定时任务类
/** * Scheduled定时任务 * * */ @Component public class ScheduledDemo { /** * 定时任务方法 * @Scheduled:设置定时任务 * cron属性:cron表达式。定时任务触发是时间的一个字符串表达形式 */ @Scheduled(cron="0/2 * * * * ?") public void scheduledMethod(){ System.out.println("定时器被触发"+new Date()); } }
|
3 在启动类中开启定时任务的使用
/** * *Scheduled * */ @SpringBootApplication @EnableScheduling public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
4 cron表达式
Cron表达式是一个字符串,分为6或7个域,每一个域代表一个含义
Cron有如下两种语法格式:
(1) Seconds Minutes Hours Day Month Week Year
(2)Seconds Minutes Hours Day Month Week
一、结构
corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
二、各字段的含义
位置 | 时间域名 | 允许值 | 允许的特殊字符 |
---|---|---|---|
1 | 秒 | 0-59 | , - * / |
2 | 分钟 | 0-59 | , - * / |
3 | 小时 | 0-23 | , - * / |
4 | 日 | 1-31 | , - * / L W C |
5 | 月 | 1-12 | , - * / |
6 | 星期 | 1-7 | , - * ? / L C # |
7 | 年(可选) | 1970-2099 | , - * / |
Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下:
●星号():可用在所有字段中,表示对应时间域的每一个时刻,例如,在分钟字段时,表示“每分钟”;
●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符;
●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;
●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;
●斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;
●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五;
●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围;
●LW组合:在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;
●井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;
● C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。
Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。
例子:
@Scheduled(cron = "0 0 1 1 1 ?")//每年一月的一号的1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 1,6 ?") //一月和六月的一号的1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 1,4,7,10 ?") //每个季度的第一个月的一号的1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 * ?")//每月一号 1:00:00 执行一次
@Scheduled(cron="0 0 1 * * *") //每天凌晨1点执行一次
二、 Spring Boot 整合 Quartz定时任务框架
1 Quartz的介绍以及Quartz的使用思路
1.1 Quartz的介绍
1.2 Quartz的使用思路
1)job - 任务 - 你要做什么事?
2)Trigger - 触发器 - 你什么时候去做?
3)Scheduler - 任务调度 - 你什么时候需要去做什么事?
2 Quartz的基本使用方式
2.1 创建项目
2.2 修改pom文件添加Quartz的坐标
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>26-quartz-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- Quartz坐标 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> </dependencies> </project> |
2.3 创建Job类
/** * 定义任务类 * * */ public class QuartzDemo implements Job { /** * 任务被触发时所执行的方法 */ public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("Execute...."+new Date()); } } |
2.4 编写测试代码
public class QuartzMain { public static void main(String[] args) throws Exception { // 1.创建Job对象:你要做什么事? JobDetail job = JobBuilder.newJob(QuartzDemo.class).build(); /** * 简单的trigger触发时间:通过Quartz提供一个方法来完成简单的重复调用 cron * Trigger:按照Cron的表达式来给定触发的时间 */ // 2.创建Trigger对象:在什么时间做? /*Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever()) .build();*/
Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) .build(); // 3.创建Scheduler对象:在什么时间做什么事? Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(job, trigger);
//启动 scheduler.start(); } } |
3 .Spring Boot整合Quartz定时框架
3.1 修改pom文件添加坐标
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>27-spring-boot-quartz</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties> <dependencies> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springBoot的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Quartz坐标 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <!-- 添加Scheduled坐标 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!-- Sprng tx 坐标 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> </dependencies> </project> |
3.2 编写Quartz的启动类
/** * Quartz配置类 * * */ @Configuration public class QuartzConfig {
/** * 1.创建Job对象 */ @Bean public JobDetailFactoryBean jobDetailFactoryBean(){ JobDetailFactoryBean factory = new JobDetailFactoryBean(); //关联我们自己的Job类 factory.setJobClass(QuartzDemo.class); return factory; }
/** * 2.创建Trigger对象 * 简单的Trigger */ @Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean(); //关联JobDetail对象 factory.setJobDetail(jobDetailFactoryBean.getObject()); //该参数表示一个执行的毫秒数 factory.setRepeatInterval(2000); //重复次数 factory.setRepeatCount(5); return factory; }
/** * 3.创建Scheduler对象 */ @Bean public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){ SchedulerFactoryBean factory = new SchedulerFactoryBean(); //关联trigger factory.setTriggers(simpleTriggerFactoryBean.getObject());
return factory; } } |
3.3 修改启动类
/** * *spring Boot 整合Quartz案例 * */ @SpringBootApplication @EnableScheduling public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } |
4 Job类中注入对象
4.1 注入时会产生异常
4.2 编写一个MyAdaptableJobFactory解决该问题
@Component("myAdaptableJobFactory") public class MyAdaptableJobFactory extends AdaptableJobFactory { //AutowireCapableBeanFactory 可以将一个对象添加到SpringIOC容器中,并且完成该对象注入 @Autowired private AutowireCapableBeanFactory autowireCapableBeanFactory;
/** * 该方法需要将实例化的任务对象手动的添加到springIOC容器中并且完成对象的注入 */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object obj = super.createJobInstance(bundle); //将obj对象添加Spring IOC容器中,并完成注入 this.autowireCapableBeanFactory.autowireBean(obj); return obj; } } |
4.3 修改QuartzConfig类
/** * Quartz配置类 * * */ @Configuration public class QuartzConfig {
/** * 1.创建Job对象 */ @Bean public JobDetailFactoryBean jobDetailFactoryBean(){ JobDetailFactoryBean factory = new JobDetailFactoryBean(); //关联我们自己的Job类 factory.setJobClass(QuartzDemo.class); return factory; }
/** * 2.创建Trigger对象 * 简单的Trigger */ /*@Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean(); //关联JobDetail对象 factory.setJobDetail(jobDetailFactoryBean.getObject()); //该参数表示一个执行的毫秒数 factory.setRepeatInterval(2000); //重复次数 factory.setRepeatCount(5); return factory; }*/
/** * Cron Trigger */ @Bean public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ CronTriggerFactoryBean factory = new CronTriggerFactoryBean(); factory.setJobDetail(jobDetailFactoryBean.getObject()); //设置触发时间 factory.setCronExpression("0/2 * * * * ?"); return factory; }
/** * 3.创建Scheduler对象 */ @Bean public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){ SchedulerFactoryBean factory = new SchedulerFactoryBean(); //关联trigger factory.setTriggers(cronTriggerFactoryBean.getObject()); factory.setJobFactory(myAdaptableJobFactory); return factory; } } |