准备

springboot 实现队列消费 springboot任务队列_定时任务

暂时只选中web模块

springboot 实现队列消费 springboot任务队列_定时任务_02

异步任务


package com.hph.task.service;

import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;

@Service
public class Asyncservice {

    public void dataprocessing() {
        Calendar ago = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        System.out.println("数据处理前"+dateFormat.format(ago.getTime()));

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("数据正在处理中......");

        Calendar now = Calendar.getInstance();
        System.out.println("数据处理完毕"+dateFormat.format(now.getTime()));
    }

}



package com.hph.task.controller;

import com.hph.task.service.Asyncservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AsyncController {
    @Autowired
    Asyncservice asyncservice;

    @GetMapping("/dataprocessing")
    public String dataprocessing() {
        asyncservice.dataprocessing();
        return "success";
    }
}


三秒之后数据有响应。

springboot 实现队列消费 springboot任务队列_定时任务_03

要完成数据的异步调用其实很简单我们只需要在SpringbootTaskApplication 开启异步注解功能


package com.hph.task;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync //开启异步注解功能
@SpringBootApplication
public class SpringbootTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootTaskApplication.class, args);
    }

}



package com.hph.task.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;

@Service
public class Asyncservice {
    @Async   //异步任务
    public void dataprocessing() {
        Calendar ago = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        System.out.println("数据处理前" + dateFormat.format(ago.getTime()));

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("数据正在处理中......");

        Calendar now = Calendar.getInstance();
        System.out.println("数据处理完毕" + dateFormat.format(now.getTime()));
    }

}


springboot 实现队列消费 springboot任务队列_定时任务_04

定时任务

定时任务可以按照自己的规则定时启动任务。


public @interface Scheduled {
	//这个cron比较重要 比较像Linux中的crontab
 
	//         秒  分   时   日   月  周几
	// {@code "0   *    *    *    *  MON-FRI"} 周一到周五每秒启动一次
	String cron() default "";

	String zone() default "";

	long fixedDelay() default -1;

	String fixedDelayString() default "";

	long fixedRate() default -1;

	String fixedRateString() default "";

	long initialDelay() default -1;

	String initialDelayString() default "";

}


准备

service


package com.hph.task.service;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;

@Service
public class ScheduledService {
    @Scheduled(cron = "0   *   *  *  *  MON-SAT") //每分钟启动一次周一到周六
    public void hello() {
        Calendar now = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        System.out.println(dateFormat.format(now.getTime())+"  定时任务启动 ..  .. .. ");
    }
}


开启注解

需要在SpringbootTaskApplication开启注解


@SpringBootApplication
@EnableScheduling   //开启基于注解的定时任务
public class SpringbootTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootTaskApplication.class, args);
    }
}


springboot 实现队列消费 springboot任务队列_定时任务_05

cron表达式

springboot 实现队列消费 springboot任务队列_spring_06


@Scheduled(cron = "0,1,2,3,4   *   *  *  *  MON-SAT") //每分钟的头1-4秒启动定时任务


springboot 实现队列消费 springboot任务队列_spring_07


@Scheduled(cron = "0-4  *   *  *  *  MON-SAT") //每分钟的头1-4秒启动定时任务


springboot 实现队列消费 springboot任务队列_springboot 实现队列消费_08


@Scheduled(cron = "0/4  *   *  *  *  MON-SAT") //每4秒启动定时任务


springboot 实现队列消费 springboot任务队列_springboot 实现队列消费_09

其他例子


* 0 * * * * MON-FRI
  *  【0 0/5 14,18 * * ?】 每天14点整,和18点整,每隔5分钟执行一次
  *  【0 15 10 ? * 1-6】 每个月的周一至周六10:15分执行一次
  *  【0 0 2 ? * 6L】每个月的最后一个周六凌晨2点执行一次
  *  【0 0 2 LW * ?】每个月的最后一个工作日凌晨2点执行一次
  *  【0 0 2-4 ? * 1#1】每个月的第一个周一凌晨2点到4点期间,每个整点都执行一次;


邮件任务

准备

我们需要在邮件中引入依赖


<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-mail</artifactId>
</dependency>


自动配置


@Configuration
@ConditionalOnClass(Session.class)
@ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
@ConditionalOnJndi
class MailSenderJndiConfiguration {

	private final MailProperties properties;

	MailSenderJndiConfiguration(MailProperties properties) {
		this.properties = properties;
	}

	@Bean   //用来发送邮件的 
	public JavaMailSenderImpl mailSender(Session session) {
		JavaMailSenderImpl sender = new JavaMailSenderImpl();
		sender.setDefaultEncoding(this.properties.getDefaultEncoding().name());
		sender.setSession(session);
		return sender;
	}

	@Bean
	@ConditionalOnMissingBean
	public Session session() {
		String jndiName = this.properties.getJndiName();
		try {
			return new JndiLocatorDelegate().lookup(jndiName, Session.class);
		}
		catch (NamingException ex) {
			throw new IllegalStateException(
					String.format("Unable to find Session in JNDI location %s", jndiName),
					ex);
		}
	}

}


可以配置的选项


@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {

	private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

	private String host;
    
	private Integer port;

	private String username;

	private String password;

	private String protocol = "smtp";

	private Charset defaultEncoding = DEFAULT_CHARSET;

	private Map<String, String> properties = new HashMap<String, String>();

	private String jndiName;
    ......
}


配置邮箱

需要将QQ邮箱中设置一下

springboot 实现队列消费 springboot任务队列_定时任务_10

application.properties中配置


spring.mail.username=467008580@qq.com
spring.mail.password=meqkusfmrwxxbhag   #授权码
spring.mail.host=smtp.qq.com


简单邮件


@Autowired
JavaMailSender mailSender;

@Test
public void sendMail() {
    SimpleMailMessage message = new SimpleMailMessage();
    //邮件设置
    message.setSubject("邮件测试通知来自QQ邮箱");
    message.setText("SpringBoot的邮件测试");
    message.setTo("han_penghui@sina.com"); //给新浪发送邮箱
    message.setFrom("467008580@qq.com");
    mailSender.send(message);
}


启动测试类

springboot 实现队列消费 springboot任务队列_springboot 实现队列消费_11

如果运行程序出错在application.properties中添加配置


spring.mail.properties.mail.smtp.ssl.enable=true


复杂邮件


//复杂邮件发送需要将第二个参数设置为ture	
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws MessagingException {
		this(mimeMessage, multipart, null);
}



@Test
public void sendMimeMail() throws MessagingException {
    //创建一个复杂的消息右键
    MimeMessage mimeMessage = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);

    helper.setSubject("复杂邮件测试来自QQ邮箱");
    helper.setText("<b style='color:red'>SpringBoot</b>的<em>邮件测试</em>",true);  //如果没有设置true默认是false,标签不生效
    helper.setTo("han_penghui@sina.com"); //给新浪发送邮箱

    //helpr上传文件
    helper.addAttachment("背景.jpg",new File("E:\\mail\\bg.jpg"));
    helper.addAttachment("Java.pdf",new File("E:\\mail\\Java知识.pdf"));
    helper.setFrom("467008580@qq.com");
    mailSender.send(mimeMessage);

}


springboot 实现队列消费 springboot任务队列_spring_12

springboot 实现队列消费 springboot任务队列_spring_13

发送成功