springboot 优雅退出-boot怎样优雅得插入一个后台线程

33737人阅读
Java(18)
JavaWeb 服务启动时,在后台启动加载一个线程。
目前,我所掌握的一共有两种方法,第一种是监听(Listener),第二种是配置随项目启动而启动的Servlet。
下面对这两种方法做一简单的介绍,(Mark一下,防止以后急用又忘记了):
监听(Listener)
首先,我们创建一个监听的类,继承ServletContextListener,如下:
package com.wxp.
import javax.servlet.ServletContextE
import javax.servlet.ServletContextL
* Listener的方式在后台执行一线程
* @author Champion.Wong
public class MyListener implements ServletContextListener {
private MyThread myT
public void contextDestroyed(ServletContextEvent e) {
if (myThread != null && myThread.isInterrupted()) {
myThread.interrupt();
public void contextInitialized(ServletContextEvent e) {
String str =
if (str == null && myThread == null) {
myThread = new MyThread();
myThread.start(); // servlet 上下文初始化时启动 socket
* 自定义一个 Class 线程类继承自线程类,重写 run() 方法,用于从后台获取并处理数据
* @author Champion.Wong
class MyThread extends Thread {
public void run() {
while (!this.isInterrupted()) {// 线程未中断执行循环
Thread.sleep(2000); //每隔2000ms执行一次
} catch (InterruptedException e) {
e.printStackTrace();
------------------ 开始执行 ---------------------------
System.out.println(&____FUCK TIME:& + System.currentTimeMillis());
然后,在web.xml中配置如下:
&listener&
&listener-class&com.wxp.thread.MyListener&/listener-class&
&/listener&
OK,启动项目,我们可以在控制台看到隔时间段输出的文字内容。
使用Servlet,在项目启动的时候启动它。
首先,创建一个Servlet,继承HttpServlet
package com.wxp.
import java.io.IOE
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import mon.C
public class MyServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
private MyThread1 myThread1;
public MyServlet(){
public void init(){
String str =
if (str == null && myThread1 == null) {
myThread1 = new MyThread1();
myThread1.start(); // servlet 上下文初始化时启动 socket
public void doGet(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)
throws ServletException, IOException{
public void destory(){
if (myThread1 != null && myThread1.isInterrupted()) {
myThread1.interrupt();
* 自定义一个 Class 线程类继承自线程类,重写 run() 方法,用于从后台获取并处理数据
* @author Champion.Wong
class MyThread1 extends Thread {
public void run() {
while (!this.isInterrupted()) {// 线程未中断执行循环
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
// ------------------ 开始执行 ---------------------------
System.out.println(&____FUCK TIME:& + System.currentTimeMillis());
然后,在web.xml中配置
&!-- LISTENER FOR THREAD --&
&servlet-name&MyListener&/servlet-name&
&servlet-class&com.ite.wxp.MyServlet&/servlet-class&
&load-on-startup&9&/load-on-startup&&!-- 数字越小,启动的优先级越高,必须大于0 --&
&/servlet&
&servlet-mapping&
&servlet-name&MyListener&/servlet-name&
&url-pattern&/test&/url-pattern&
&/servlet-mapping&
OK。启动项目,依然可以看到如图所示:
&&&&&&&&&&&&&&&&&&&&&&&&&& 其中,Listener的方式,该线程肯定是项目中首先启动的,优先于任何一个Servlet。而Servlet的方式,可以设置与其它Servlet启动的顺序。如果有时候需要首先启动一个Servlet或者它们之间的启动顺序有特殊要求的时候,这个就很有作用了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:365463次
积分:3399
积分:3399
排名:第10034名
原创:44篇
评论:64条
(1)(1)(1)(1)(5)(2)(2)(7)(1)(4)(1)(4)(1)(1)(2)(3)(2)(1)(1)(2)(2)(2)(2)Spring Boot使用自定义的properties - 汪云飞记录本 - ITeye博客
博客分类:
spring boot使用application.properties默认了很多配置。但需要自己添加一些配置的时候,我们应该怎么做呢。
若继续在application.properties中添加
wisely2.name=wyf2
wisely2.gender=male2
定义配置类:
@ConfigurationProperties(prefix = "wisely2")
public class Wisely2Settings {
public String getName() {
public void setName(String name) {
this.name =
public String getGender() {
public void setGender(String gender) {
this.gender =
若新用新的配置文件
如我新建一个wisely.properties
wisely.name=wangyunfei
wisely.gender=male
需定义如下配置类
@ConfigurationProperties(prefix = "wisely",locations = "classpath:config/wisely.properties")
public class WiselySettings {
public String getName() {
public void setName(String name) {
this.name =
public String getGender() {
public void setGender(String gender) {
this.gender =
最后注意在spring Boot入口类加上@EnableConfigurationProperties
@SpringBootApplication
@EnableConfigurationProperties({WiselySettings.class,Wisely2Settings.class})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
使用定义的properties
在别的bean中可直接注入
@Controller
public class TestController {
@Autowired
WiselySettings wiselyS
@Autowired
Wisely2Settings wisely2S
@RequestMapping("/test")
public @ResponseBody String test(){
System.out.println(wiselySettings.getGender()+"---"+wiselySettings.getName());
System.out.println(wisely2Settings.getGender()+"==="+wisely2Settings.getGender());
return "ok";
新书推荐《JavaEE开发的颠覆者: Spring Boot实战》,涵盖Spring 4.x、Spring MVC 4.x、Spring Boot企业开发实战。
京东地址:
当当地址:
亚马逊地址:
或自己在京东、淘宝、亚马逊、当当、互动出版社搜索自选。
浏览 96739
locations 这个属性没了?看看这个文章http://fabiomaffioletti.me/blog//spring-configuration-properties-locations-deprecation-another-approach/
locations 这个属性没了?我也发现没了,这可如何是好
如果我有一个配置类和多个格式相同内容不同的配置文件,我想根据这几个配置文件生成几个不同的配置类实例,用注解应该怎么做?找到了定义好类public class DataConfig { private S private String driverClassN private S private S private T&&&&&&& ...getter and setter...}在配置类里面定义@Configurationpublic class PropertiesConfTest { @Bean(name="edmsDataConfig") @ConfigurationProperties(prefix = "datasource.edms") public DataConfig edmsDataConfig(){
return new DataConfig(); } @Bean(name="uicDataConfig") @ConfigurationProperties(prefix = "datasource.uic") public DataConfig uicDataConfig(){
return new DataConfig(); }}
如果我有一个配置类和多个格式相同内容不同的配置文件,我想根据这几个配置文件生成几个不同的配置类实例,用注解应该怎么做?我也有这个问题,不知道怎么处理
你书里的源代码在哪下载啊?.cn/?#book/bookdetail/bookDetailAll.jsp?book_id=b47a1c54--b3e2-b8bc4899a97e&isbn=978-7-121-28208-9
浏览: 1070424 次
来自: 合肥
浏览量:47607
浏览量:83924
jjianwen68 写道使用两个configuration来 ...
P208 代码解释 pinciple -& princi ...
141页 6.1.5 starter pom 上面一行 附录
楼主 我又来找错误了,嘿嘿116 页 代码解释 1 第一行 A ...
ytfcelss 写道第11章 springboot-actu ...这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis。到网上找了一下关于spring&boot和mybatis组合的相关资料,各种各样的形式都有,看的人心累,结合了mybatis的官方demo和文档终于找到了最简的两种模式,花了一天时间总结后分享出来。
orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis。
hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据方法名就可以生成对应的sql了,有不太了解的可以看我的上篇文章springboot(五):spring data jpa的使用。
mybatis初期使用比较麻烦,需要各种配置文件、实体类、dao层映射关联、还有一大推其它配置。当然mybatis也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和dao层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这种模式了,mybatis-spring-boot-starter就是springboot+mybatis可以完全注解不用配置文件,也可以简单配置轻松上手。
现在想想spring boot 就是牛逼呀,任何东西只要关联到spring boot都是化繁为简。
mybatis-spring-boot-starter
官方说明:MyBatis Spring-Boot-Starter will help you use MyBatis with Spring Boot&其实就是myBatis看spring boot这么火热也开发出一套解决方案来凑凑热闹,但这一凑确实解决了很多问题,使用起来确实顺畅了许多。mybatis-spring-boot-starter主要有两种解决方案,一种是使用注解解决一切问题,一种是简化后的老传统。
现在去&http://start.spring.io/ 新建一个项目&spring-boot-mybatis-annotation 注解版本
当然任何模式都需要首先引入mybatis-spring-boot-starter的pom文件,现在最新版本是1.1.1(刚好快到双11了 :))
&dependency&
&groupId&org.mybatis.spring.boot&/groupId&
&artifactId&mybatis-spring-boot-starter&/artifactId&
&version&1.1.1&/version&
&/dependency&
好了下来分别介绍两种开发模式
无配置文件注解版
就是一切使用注解搞定。
1 添加相关maven文件
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-web&/artifactId&
&/dependency&
&dependency&
&groupId&org.mybatis.spring.boot&/groupId&
&artifactId&mybatis-spring-boot-starter&/artifactId&
&version&1.1.1&/version&
&/dependency&
&dependency&
&groupId&mysql&/groupId&
&artifactId&mysql-connector-java&/artifactId&
&/dependency&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-devtools&/artifactId&
&optional&true&/optional&
&/dependency&
完整的pom包这里就不贴了,大家直接看源码,或者自动生成的就只有 需要添加上面的
2、application.properties&添加相关配置
mybatis.type-aliases-package=com.neo.entity
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root
springboot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,对了你一切都不用管了,直接拿起来使用就行了。
在启动类中添加对mapper包扫描@MapperScan
修改 src/main/java下的 Application.java
@SpringBootApplication
@MapperScan("com.neo.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
或者直接在Mapper类上面添加注解@Mapper,建议使用上面那种,不然每个mapper加个注解也挺麻烦的
3、开发Mapper
第三步是最关键的一块,sql生产都在这里 首先新建entity enums mapper web层
在enums层里面新建一个enum
public enum UserSexEnum {
MAN , WOMAN
在entity里面 新建UserEntity类 如下
public class UserEntity implements Serializable {
private String userN
private String passW
private UserSexEnum userS
private String nickN
public UserEntity() {
public UserEntity(String userName, String passWord, UserSexEnum userSex) {
this.userName = userN
this.passWord = passW
this.userSex = userS
public Long getId() {
public void setId(Long id) {
public String getUserName() {
return userN
public void setUserName(String userName) {
this.userName = userN
public String getPassWord() {
return passW
public void setPassWord(String passWord) {
this.passWord = passW
public UserSexEnum getUserSex() {
return userS
public void setUserSex(UserSexEnum userSex) {
this.userSex = userS
public String getNickName() {
return nickN
public void setNickName(String nickName) {
this.nickName = nickN
public String toString() {
return "UserEntity [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", userSex=" + userSex
+ ", nickName=" + nickName + "]";
在mapper 里面新建一个Interface
---恢复内容结束---
这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis。到网上找了一下关于spring&boot和mybatis组合的相关资料,各种各样的形式都有,看的人心累,结合了mybatis的官方demo和文档终于找到了最简的两种模式,花了一天时间总结后分享出来。
orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis。
hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据方法名就可以生成对应的sql了,有不太了解的可以看我的上篇文章springboot(五):spring data jpa的使用。
mybatis初期使用比较麻烦,需要各种配置文件、实体类、dao层映射关联、还有一大推其它配置。当然mybatis也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和dao层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这种模式了,mybatis-spring-boot-starter就是springboot+mybatis可以完全注解不用配置文件,也可以简单配置轻松上手。
现在想想spring boot 就是牛逼呀,任何东西只要关联到spring boot都是化繁为简。
mybatis-spring-boot-starter
官方说明:MyBatis Spring-Boot-Starter will help you use MyBatis with Spring Boot&其实就是myBatis看spring boot这么火热也开发出一套解决方案来凑凑热闹,但这一凑确实解决了很多问题,使用起来确实顺畅了许多。mybatis-spring-boot-starter主要有两种解决方案,一种是使用注解解决一切问题,一种是简化后的老传统。
现在去&http://start.spring.io/ 新建一个项目&spring-boot-mybatis-annotation 注解版本
当然任何模式都需要首先引入mybatis-spring-boot-starter的pom文件,现在最新版本是1.1.1(刚好快到双11了 :))
&dependency&
&groupId&org.mybatis.spring.boot&/groupId&
&artifactId&mybatis-spring-boot-starter&/artifactId&
&version&1.1.1&/version&
&/dependency&
好了下来分别介绍两种开发模式
无配置文件注解版
就是一切使用注解搞定。
1 添加相关maven文件
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-web&/artifactId&
&/dependency&
&dependency&
&groupId&org.mybatis.spring.boot&/groupId&
&artifactId&mybatis-spring-boot-starter&/artifactId&
&version&1.1.1&/version&
&/dependency&
&dependency&
&groupId&mysql&/groupId&
&artifactId&mysql-connector-java&/artifactId&
&/dependency&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-devtools&/artifactId&
&optional&true&/optional&
&/dependency&
完整的pom包这里就不贴了,大家直接看源码,或者自动生成的就只有 需要添加上面的
2、application.properties&添加相关配置
mybatis.type-aliases-package=com.neo.entity
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root
springboot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,对了你一切都不用管了,直接拿起来使用就行了。
在启动类中添加对mapper包扫描@MapperScan
修改 src/main/java下的 Application.java
@SpringBootApplication
@MapperScan("com.neo.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
或者直接在Mapper类上面添加注解@Mapper,建议使用上面那种,不然每个mapper加个注解也挺麻烦的
3、开发Mapper
第三步是最关键的一块,sql生产都在这里 首先新建entity enums mapper web层
在enums层里面新建一个enum
public enum UserSexEnum {
MAN , WOMAN
在entity里面 新建UserEntity类 如下
public class UserEntity implements Serializable {
private String userN
private String passW
private UserSexEnum userS
private String nickN
public UserEntity() {
public UserEntity(String userName, String passWord, UserSexEnum userSex) {
this.userName = userN
this.passWord = passW
this.userSex = userS
public Long getId() {
public void setId(Long id) {
public String getUserName() {
return userN
public void setUserName(String userName) {
this.userName = userN
public String getPassWord() {
return passW
public void setPassWord(String passWord) {
this.passWord = passW
public UserSexEnum getUserSex() {
return userS
public void setUserSex(UserSexEnum userSex) {
this.userSex = userS
public String getNickName() {
return nickN
public void setNickName(String nickName) {
this.nickName = nickN
public String toString() {
return "UserEntity [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", userSex=" + userSex
+ ", nickName=" + nickName + "]";
在mapper 里面新建一个Interface
public interface UserMapper {
@Select("SELECT * FROM users")
@Results({
@Result(property = "userSex",
column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
List&UserEntity& getAll();
@Select("SELECT * FROM users WHERE id = #{id}")
@Results({
@Result(property = "userSex",
column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
UserEntity getOne(Long id);
@Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
void insert(UserEntity user);
@Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
void update(UserEntity user);
@Delete("DELETE FROM users WHERE id =#{id}")
void delete(Long id);
为了更接近生产我特地将user_sex、nick_name两个属性在数据库加了下划线和实体类属性名不一致,另外user_sex使用了枚举
@Select 是查询类的注解,所有的查询均使用这个
@Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
@Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
@Update 负责修改,也可以直接传入对象
@delete 负责删除
注意,使用#符号和$符号的不同:
// This example creates a prepared statement, something like select * from teacher where name = ?;
@Select("Select * from teacher where name = #{name}")
Teacher selectTeachForGivenName(@Param("name") String name);
// This example creates n inlined statement, something like select * from teacher where name = 'someName';
@Select("Select * from teacher where name = '${name}'")
Teacher selectTeachForGivenName(@Param("name") String name);
上面三步就基本完成了相关dao层开发,使用的时候当作普通的类注入进入就可以了
阅读(...) 评论()

我要回帖

更多关于 spring boot 的文章

 

随机推荐