異步任務
在Java應用中,絕大多數情況下都是通過同步的方式來實現交互處理的;但是在處理與第三方系統交互的時候,容易造成響應遲緩的情況,之前大部分都是使用多線程來完成此類任務,其實,在Spring 3.x之後,就已經內置了@Async
來完美解決這個問題。
註解使用
在SpringBoot裏,需要給啓動類添加@EnableAsync
來開啓異步註解。
使用@Async
異步註解:
@Service
public class AsyncService {
@Async // 該註解表明這是一個異步任務
public void hello(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("處理數據中...");
}
}
定時任務
一、@Scheduled
項目開發中經常需要執行一些定時任務
,比如需要在每天凌晨時候,分析一次前一天的日誌信息,統計前一天的商品銷量等。Spring爲我們提供了異步執行任務調度的方式,提供TaskExecutor
、TaskScheduler
接口。
要使用同步任務,首先需要了解SpringTask以及Cron表達式
註解使用
在SpringBoot裏,需要給啓動類添加@EnableScheduling
來開啓定時任務註解。
使用@Scheduled
定時任務註解:
@Service
public class ScheduleService {
/**
* Cron表達式
*/
@Scheduled(cron = "0/4 * * * * MON-SAT") // 每4秒執行一次
public void hello(){
System.out.println("hello...");
}
/**
* initialDelay:首次執行任務的延遲
* fixedRate:當前任務開始執行2000ms之後開啓另一個定時任務
*/
@Scheduled(initialDelay = 1000,fixedRate = 2000)
public void world(){
System.out.println("world...");
}
/**
* fixedDelay:當前任務執行結束1000ms之後開啓另一個任務
*/
@Sheduled(fixedDelay = 1000)
public void test(){
System.out.println("text...");
}
}
二、Quartz
Quartz 是一個功能豐富的開源作業調度庫,它由 Java 寫成,可以集成在任何 Java 應用程序中,
包括 Java SE 和 Java EE 等。使用 Quartz 可以創建簡單或者複雜的執行計劃,它支持數據庫、集羣、插件以及郵件,並且支持 cron 表達式,具有極高的靈活性。
1、引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2、創建兩個任務
①普通JavaBean
@Component
public class MyFirstJob {
public void firstJob(){
System.out.println("MyFirstJob:firstJob-" + new Date());
}
}
②繼承QuartzJobBean
public class MySecondJob extends QuartzJobBean{
private String name;
public void setName(String name){
this.name = name;
}
/**
* 任務被調用時使用
*/
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext){
System.out.println("SecondJob:" + name + "-" + new Date());
}
}
3、配置任務
@Configuration
public class QuartzConfig {
/**
* JobDetail配置方式一
* 該方式只需要指定:實例名、方法名
* 缺點:無法傳遞參數
*/
@Bean
public MethodInvokingJobDetailFactoryBean jobDetail1(){
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
bean.setTargetBeanName("myFirstJob");
bean.setTargetMethod("firstJob");
return bean;
}
/**
* JobDetail配置方式二
* 該方式只需要指定:JobClass - 即繼承QuartzJobBean的類
* 優點:可以通過jobDataMap傳遞參數,key與Job中的屬性名一致即可,且Job中的屬性要提供set方法
*/
@Bean
public JobDetailFactoryBean jobDetail2(){
JobDetailFactoryBean bean = new JobDetailFactoryBean();
bean.setJobClass(MySecondJob.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("name","LCY");
bean.setJobDataMap(jobDataMap);
bean.setDurability(true);
return bean;
}
/**
* Trigger常見實現方式一
*/
@Bean
public SimpleTriggerFactoryBean simpleTrigger(){
SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
bean.setJobDetail(jobDetail1().getObject());
// 任務循環次數
bean.setRepeatCount(3);
// 任務啓動延遲時間
bean.setStartDelay(1000);
// 任務時間間隔
bean.setRepeatInterval(2000);
return bean;
}
/**
* Trigger常見實現方式二
*/
@Bean
public CronTriggerFactoryBean cronTrigger(){
CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
bean.setJobDetail(jobDetail2().getObject());
// Corn表達式 - 每秒執行一次
bean.setCronExpression("* * * * * ?");
return bean;
}
/**
* 創建SchedulerFactory
*/
@Bean
public SchedulerFactoryBean schedulerFactory(){
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 配置Trigger
SimpleTrigger simpleTrigger = simpleTrigger().getObject();
CronTrigger cronTrigger = cronTrigger().getObject();
// Trigger多參數
bean.setTriggers(simpleTrigger,cronTrigger);
return bean;
}
}
4、測試結果
郵件任務
郵件任務在項目中也比較常見,比如用戶註冊,我們可以通過郵件的方式確認註冊信息(驗證碼),註冊成功了,發送一些有關的信息等等。
原理
[email protected]
要給[email protected]
發送郵件,它們不是直接交互的。而是lcy要登錄自己的郵箱服務器,登進來以後以這個賬戶爲名,給jyqc發郵件。而給jyqc發郵件,也是qq郵箱服務器發給163郵箱服務器,163郵箱服務器再發給jyqc的。
一、依賴引入及自動配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
自動配置
配置文件內容
二、開啓郵箱服務
以QQ郵箱爲例
,需要開啓這些服務:
然後我們就可以點擊生成授權碼,在yml
配置文件中使用。
三、配置yml
主要需要配置郵箱的賬號
、密碼(授權碼)
、郵箱主機地址
spring:
mail:
username: 123456789@qq.com # 郵箱
password: vzydizxcystfkwefi # 授權碼
host: smtp.qq.com # QQ郵箱主機地址
default-encoding: utf-8 # 編碼,默認UTF-8
properties:
mail:
smtp:
ssl:
enable: true # 安全的ssl鏈接
四、簡單郵件發送
注入JavaMailSenderImpl
。
@Autowired
private JavaMailSenderImpl mailSender;
@Test
public void test(){
// 簡單郵件信息對象
SimpleMailMessage message = new SimpleMailMessage();
// 郵件標題
message.setSubject("尋寶遊戲註冊驗證碼:");
// 郵件內容
message.setText("驗證碼:123456");
// 郵件接收方
message.setTo("[email protected]");
// 郵件發送方
message.setFrom("[email protected]");
// 發送
mailSender.send(message);
}
五、複雜郵件發送
@Test
public void test1(){
try {
// 複雜的消息郵件對象
MimeMessage mimeMessage = mailSender.createMimeMessage();
// 參數2:是否上傳文件
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
// 郵件標題
helper.setSubject("尋寶遊戲註冊");
// 設置內容 - 參數2:是否使用html格式
helper.setText("<em style='color:red'>註冊成功!請閱讀附件!</em>",true);
// 郵件接收方
helper.setTo("[email protected]");
// 郵件發送方
helper.setFrom("[email protected]");
//上傳文件
helper.addAttachment("1.jpg",new File("D:\\1.jpg"));
helper.addAttachment("2.jpg",new File("D:\\2.jpg"));
// 發送
mailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}