java.util.Time结合Spring发送Email

本文介绍了如何使用Java中的Timer类来实现简单的定时任务。详细解释了Timer与TimerTask的基本用法,包括如何创建和执行定时任务,以及如何取消任务。通过一个具体的例子展示了如何配置并运行一个定时发送消息的任务。
参考资料
1 Web项目下应用Java Timer定时器
[url]http://www.zjava.net/a/j2ee/zh/2011/0510/1175.html[/url]
2 JAVA Timer定时任务
[url]http://blog.sina.com.cn/s/blog_52e0c6cf0100ia2u.html[/url]
3 java定时器的使用(Timer)
[url]http://www.cnblogs.com/wyqtomorrow/archive/2007/04/28/730978.html[/url]
4 用java.util.Timer定时执行任务
[url]http://www.blogjava.net/georgehill/archive/2005/06/09/5793.aspx[/url]

请参见:
Spring之Email<封装了常用的四种发送Email的方法(TEXT,HTML,IMG,FILE)>
[url]http://liuzidong.iteye.com/blog/1114783[/url]
这个例子中用到了它的: MailMessageFactory
[b]介绍[/b]
[color=red]如果要执行一些简单的定时器任务,无须做复杂的控制,也无须保存状态,那么可以考虑使用JDK 入门级的定期器Timer来执行重复任务[/color]。

[b]JDK中,定时器任务的执行需要两个基本的类:
java.util.Timer;
java.util.TimerTask;[/b]

要运行一个定时任务,最基本的步骤如下:
[color=blue]1、建立一个要执行的任务TimerTask。
2、创建一个Timer实例,通过Timer提供的schedule()方法,将TimerTask加入到定时器Timer中,同时设置执行的规则即可。
当程序执行了Timer初始化代码后,Timer定时任务就会按照设置去执行。
Timer中的schedule()方法是有多种重载格式的,以适应不同的情况。该方法的格式如下[/color]:

[i] void schedule(TimerTask task, Date time)
安排在指定的时间执行指定的任务。
void schedule(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定延迟执行。
void schedule(TimerTask task, long delay)
安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行[/i]

Timer是线程安全的,此类可扩展到大量同时安排的任务(存在数千个都没有问题)。其所有构造方法都启动计时器线程。可以[b]调用cancel() 终止此计时器[/b],丢弃所有当前已安排的任务。[b]purge()从此计时器的任务队列中移除所有已取消的任务[/b]。此类不提供实时保证:它使用 Object.wait(long) 方法来安排任务。

TimerTask是一个抽象类,由 Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()----计时器任务要执行的操作。因此,每个具体的任务类都必须继承TimerTask类,并且重写run()方法。另外它还有两个非抽象的方法:
[color=brown] boolean cancel() 取消此计时器任务。
long scheduledExecutionTime() 返回此任务最近实际 执行的安排 执行时间。[/color]

二 代码如下:

public class SendMessageTime extends TimerTask{
//消息计数器
private static int messageCount = 0;
//发送标题
private String subject;
private String text;
private MailMessageFactory mms;

public String getSubject() {
return subject;
}

public void setSubject(String subject) {
this.subject = subject;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

@Override
public void run() {
System.out.println("开始发送消息...");
mms = new MailMessageFactory();
mms.setSubject(getSubject())
.setText(getText())
.send();
System.out.println("发送消息条数: "+(++messageCount));
}
}


测试类

public class TimeTest {

public static void main(String[] args) {

java.util.Timer timer = new java.util.Timer(true);
//消息发送器
SendMessageTime task = new SendMessageTime();
task.setSubject("测试java.util.Time类定时发送消息");
task.setText("TimerTask是一个抽象类,由 Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()----计时器任务要执行的操作。" +
"因此,每个具体的任务类都必须继承TimerTask类,并且重写run()方法。另外它还有两个非抽象的方法");

long delay = 1000;
long period = 2000;
//从现在起过delay毫秒以后,每隔period 毫秒执行一次
timer.schedule(task,delay,period);
//休眠30秒后结束进程
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.cancel();
timer.cancel();
System.out.println("结束发送消息....");
}
}

后台打印信息如下:

开始发送消息...
发送文本消息成功!,耗费时间: 1718毫秒!
发送消息条数: 1
开始发送消息...
发送文本消息成功!,耗费时间: 969毫秒!
发送消息条数: 2
开始发送消息...
发送文本消息成功!,耗费时间: 1125毫秒!
发送消息条数: 3
开始发送消息...
发送文本消息成功!,耗费时间: 766毫秒!
发送消息条数: 4
开始发送消息...
发送文本消息成功!,耗费时间: 907毫秒!
发送消息条数: 5
开始发送消息...
发送文本消息成功!,耗费时间: 766毫秒!
发送消息条数: 6
开始发送消息...
发送文本消息成功!,耗费时间: 4110毫秒!
发送消息条数: 7
开始发送消息...
发送文本消息成功!,耗费时间: 1140毫秒!
发送消息条数: 8
开始发送消息...
发送文本消息成功!,耗费时间: 4203毫秒!
发送消息条数: 9
开始发送消息...
发送文本消息成功!,耗费时间: 953毫秒!
发送消息条数: 10
开始发送消息...
结束发送消息....
获取当天日期 获取本周一日期 获取本周日的日期 获取上周一日期:" + tt.getPreviousWeekday("yyyy-MM-dd")); 获取上周日日期:" + tt.getPreviousWeekSunday("yyyy-MM-dd")); 获取上周一日期:" + tt.getWeekday(-1, "yyyy-MM-dd")); 获取上周日日期:" + tt.getWeekSunday(-1, "yyyy-MM-dd")); 获取下周一日期:" + tt.getNextMonday("yyyy-MM-dd")); 获取下周日日期:" + tt.getNextSunday("yyyy-MM-dd")); 获取本月第一天日期:" + tt.getFirstDayOfMonth()); 获取本月最后一天日期:" + tt.getDefaultDay()); 获取上月第一天日期:" + tt.getPreviousMonthFirst("yyyy-MM-dd")); 获取上月最后一天的日期:" + tt.getPreviousMonthEnd("yyyy-MM-dd")); 获取某月第一天日期:" + tt.getMonthFirst(0, "yyyy-MM-dd")); 获取某月最后一天的日期:" + tt.getMonthEnd(0, "yyyy-MM-dd")); 获取下月第一天日期:" + tt.getNextMonthFirst("yyyy-MM-dd")); 获取下月最后一天日期:" + tt.getNextMonthEnd("yyyy-MM-dd")); 获取本年的第一天日期:" + tt.getCurrentYearFirst()); 获取本年最后一天日期:" + tt.getCurrentYearEnd()); 获取去年的第一天日期:" + tt.getPreviousYearFirst()); 获取去年的最后一天日期:" + tt.getPreviousYearEnd()); 获取明年第一天日期:" + tt.getNextYearFirst()); 获取明年最后一天日期:" + tt.getNextYearEnd()); 获取本季度第一天:" + tt.getThisSeasonFirstTime(11)); 获取本季度最后一天:" + tt.getThisSeasonFinallyTime(11)); 获取两个日期之间间隔天数 获取当前月的第几周:" + tt.getWeekOfMonth()); 获取当前年份:" + tt.getYear()); 获取当前月份:" + tt.getMonth()); 获取今天在本年的第几天:" + tt.getDayOfYear()); 获得今天在本月的第几天(获得当前日):" + tt.getDayOfMonth()); 获得今天在本周的第几天:" + tt.getDayOfWeek()); 字符串转时间 获得一个日期所在周的星期几的日期
现在这三个部分的代码是 package com.example.club.entity; public enum Status { PENDING, APPROVED,SUSPENDED,REJECTED } package com.example.club.util; import com.example.club.entity.Role; import com.example.club.entity.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.Collections; public class CustomUserDetails implements UserDetails { private final User user; public CustomUserDetails(User user) { this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return Collections.singletonList( new SimpleGrantedAuthority("ROLE_" + user.getRole().name()) ); } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return user.getStatus() == Status.APPROVED; } public User getUser() { return user; } } package com.example.club.entity; import lombok.Data; import javax.persistence.*; import java.util.List; @Entity @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false) private String password; @Column(nullable = false) private String email; private String realName; private String profilePic; @Enumerated(EnumType.STRING) private Role role; @Enumerated(EnumType.STRING) private Status status; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Blog> blogs; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Friendship> friendships; @OneToMany(mappedBy = "friend", cascade = CascadeType.ALL, orphanRemoval = true) private List<Friendship> friendOf; }
06-25
rg.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `org.springframework.security.core.authority.SimpleGrantedAuthority` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (byte[])"{"@class":"com.yejiali.backend.entity.MyUserDetails","user":{"@class":"com.yejiali.backend.entity.User","id":11,"username":"bbb","password":"$2a$10$ETfXTIbWnRibT1NzDuloX.WytSiUpm2Pze6TNoXLHud9p9zhzjkFq","realName":null,"role":null,"avatar":null,"phonenumber":null,"email":null,"updataTime":["java.util.Date",1747105503000],"createTime":["java.util.Date",1747105503000],"lastLogin":null,"delFlag":0},"authorities":["java.util.ArrayList",[{"@class":"org.springframework.security.core.authority.SimpleGr"[truncated 230 bytes]; line: 1, column: 517] (through reference chain: com.yejiali.backend.entity.MyUserDetails["authorities"]->java.util.ArrayList[0]) at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:239) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:216) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:360) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:62) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:406) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:373) ~[spring-data-redis-3.0.1.jar:3.0.1] at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97) ~[spring-data-redis-3.0.
05-15
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mysqlUserRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property getOne found for type UserInfo! at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1271) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595) ~[spring-beans-5.1.15.RELEASE.jar:5.1.15.RELEASE] ... 32 common frames omitted Caused by: org.springframework.data.mapping.PropertyReferenceException: No property getOne found for type UserInfo! at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:382) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:358) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:311) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) ~[na:1.8.0_462-462] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:293) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:276) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE] at org.springframework.data.repository.query.parser.Part.<init>(Part.java:82) ~[spring-data-commons-2.1.17.RELEASE.jar:2.1.17.RELEASE]
最新发布
08-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值