文章目录

  • Spring学习(下)
    • 专题三:JavaMail邮件发送
      • API与环境配置
      • 代码实现
    • 专题四:AOP
      • aop概念特点
      • aop注解实现
      • 代理--静态代理实现
      • 代理--动态代理实现--JDK实现
      • 代理--动态代理--CGLIB实现
    • 专题五:定时任务
      • 1:概述
      • 2:quartz
      • 3:时间解析

Spring学习(下)

专题三:JavaMail邮件发送

API与环境配置

JavaMail是一套收发电子邮件的API,未包含在JDK中,而是作为JavaEE的一部分。

厂商可以提供自己的实现类,有选择地实现某些邮件协议:

SMTP(Simple Mail Transport Protocal):简单邮件传输协议 POP3:接收电子邮件的标准协议 IMAP:互联网消息协议,是POP3的替代协议 都有对应SSL加密传输的协议,SMTPS,POP3S,IMAPS。

除javamail服务提供程序外,

还需要JAF(JavaBeans Activation Framework)来处理不是纯文本的邮件内容,
这包括MIME(多用途互联网邮件扩展Multipurpose Internet Mail Extensions),URL页面和文件附件等内容。JAF在java6之后已经合并到JDK中。

流程:邮件发送投递到邮箱服务器(163,126,139等)–> 对方登录到客户端之后,下载邮件到本地

JavaMail的关键对象

1:Properties属性对象

javamail通过properties对象封装诸多属性信息比如:服务器地址,端口,用户名,密码等。

2:Session会话对象

这里的session只是一对配置信息的集合,不是httpsession。作用是:<1>接收各种配置属性信息。<2>初始化javamail环境,根据javamail的配置文件。

3:Transport和Store:传输与存储

邮件操作只有发送与接收两种处理方式,传输对应邮件的发送,存储对应邮件的接收。

4:Message消息对象

此为一个抽象类,必须使用一个子类,通常为MimeMessage;

5:Address:地址

也是一个抽象类,用InternetAddress类。

6:Authenticator:认证者

访问邮箱服务器用这个进行用户名与密码进行认证,也是抽象类,有默认实现类。

代码实现
//普通邮件发送
public static void mail01(){Message message = null;Session session = null;Properties properties = null;try {properties = new Properties();//设置邮箱服务器域名properties.put("mail.smtp.host","smtp.126.com");//设置邮箱端口号,一般为25properties.put("mail.smtp.port","25");//设置邮箱认证的标识properties.put("mail.smtp.auth",true);session = Session.getDefaultInstance(properties,new MyAuthenticator("linghe***n@126.com","**"));message = new MimeMessage(session);//补全message/*1,邮件消息发送人,接收人2,消息主题3,邮件内容*/Address address = new InternetAddress("linghefei**@126.com");//设置发送人message.setFrom(address);//设置接收人message.setRecipients(Message.RecipientType.TO,new InternetAddress[]{new InternetAddress("*****")});//设置主题message.setSubject("java mail待你查收!");//设置内容message.setText("你好吗?!");Transport.send(message);} catch (Exception e) {e.printStackTrace();}}class MyAuthenticator extends Authenticator{private String userName;private String password;public MyAuthenticator(String userName, String password) {this.userName = userName;this.password = password;}@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(userName, password);}
}
//html邮件发送
public static void mail02(){Message message = null;Session session = null;Properties properties = null;Multipart multipart = null;BodyPart bodyPart = null;try {properties = new Properties();//设置邮箱服务器域名properties.put("mail.smtp.host","smtp.126.com");//设置邮箱端口号,一般为25properties.put("mail.smtp.port","25");//设置邮箱认证的标识properties.put("mail.smtp.auth",true);session = Session.getDefaultInstance(properties,new MyAuthenticator("lingh*****@126.com","***"));message = new MimeMessage(session);//补全message/*1,邮件消息发送人,接收人2,消息主题3,邮件内容html*/Address address = new InternetAddress("ling***@126.com");//设置发送人message.setFrom(address);//设置接收人message.setRecipients(Message.RecipientType.TO,new InternetAddress[]{new InternetAddress("*******")});//设置主题message.setSubject("java mail待你查收!");//设置内容multipart = new MimeMultipart();bodyPart = new MimeBodyPart();bodyPart.setContent("<image src='https://www.baidu.com/img/dong_8f1d47bcb77d74a1e029d8cbb3b33854.gif'/><a herf='https://www.baidu.com'>百度</a>","text/html;charset=utf-8");multipart.addBodyPart(bodyPart);message.setContent(multipart);Transport.send(message);} catch (Exception e) {e.printStackTrace();}}
//html邮件+附件public static void mail03(){Message message = null;Session session = null;Properties properties = null;Multipart multipart = null;BodyPart bodyPart = null;try {properties = new Properties();//设置邮箱服务器域名properties.put("mail.smtp.host","smtp.126.com");//设置邮箱端口号,一般为25properties.put("mail.smtp.port","25");//设置邮箱认证的标识properties.put("mail.smtp.auth",true);session = Session.getDefaultInstance(properties,new MyAuthenticator("l***@126.com","***50"));message = new MimeMessage(session);//补全message/*1,邮件消息发送人,接收人2,消息主题3,邮件内容html*/Address address = new InternetAddress("li***@126.com");//设置发送人message.setFrom(address);//设置接收人message.setRecipients(Message.RecipientType.TO,new InternetAddress[]{new InternetAddress("h****")});//设置主题message.setSubject("java mail待你查收!");//设置内容multipart = new MimeMultipart();bodyPart = new MimeBodyPart();bodyPart.setContent("<image src='https://www.baidu.com/img/dong_8f1d47bcb77d74a1e029d8cbb3b33854.gif'/><a herf='https://www.baidu.com'>百度</a>","text/html;charset=utf-8");multipart.addBodyPart(bodyPart);//html内容添加//添加附件:bodyPart = new MimeBodyPart();//重新将变量调整下指向bodyPart.setDataHandler(new DataHandler(new FileDataSource(new File("what.txt"))));bodyPart.setFileName("what.txt");//防止中文名称下客户端服务端编码不统一而乱码:
//            bodyPart.setFileName(MimeUtility.encodeText("what.txt"));multipart.addBodyPart(bodyPart);//附件添加message.setContent(multipart);Transport.send(message);} catch (Exception e) {e.printStackTrace();}}

代码封装:

@SuppressWarnings("all")
@Component
public class MailSender {public void sendMail(String from, String[] to, String subject, String content, String[] files) {//参数校验/*from邮箱格式的合法性to非空 邮箱格式合法subject非空content非空*/Message message = null;Session session = null;Properties properties = null;Multipart multipart = null;BodyPart bodyPart = null;try {properties = new Properties();//设置邮箱服务器域名properties.put("mail.smtp.host", "smtp.126.com");//设置邮箱端口号,一般为25properties.put("mail.smtp.port", "25");//设置邮箱认证的标识properties.put("mail.smtp.auth", true);session = Session.getDefaultInstance(properties, new MyAuthenticator("lingh***com", "**"));message = new MimeMessage(session);//补全message/*1,邮件消息发送人,接收人2,消息主题3,邮件内容html*/Address address = new InternetAddress(from);//设置发送人message.setFrom(address);//设置接收人//构建接收方InternetAddress[] receivers = new InternetAddress[to.length];for (int i = 0; i < to.length; i++) {receivers[i] = new InternetAddress(to[i]);}message.setRecipients(Message.RecipientType.TO, receivers);//设置主题String subjectAfter = MimeUtility.encodeWord(subject, "UTF-8", "Q");message.setSubject(subjectAfter);//设置内容multipart = new MimeMultipart();bodyPart = new MimeBodyPart();
//            "<image src='https://www.baidu.com/img/dong_8f1d47bcb77d74a1e029d8cbb3b33854.gif'/><a herf='https://www.baidu.com'>百度</a>"bodyPart.setContent(content, "text/html;charset=utf-8");multipart.addBodyPart(bodyPart);//html内容添加//因为附件可添加可不添加:if (null != files && files.length > 0) {for (String file : files) {File temp = new File(file);//添加附件:bodyPart = new MimeBodyPart();//重新将变量调整下指向bodyPart.setDataHandler(new DataHandler(new FileDataSource(temp)));bodyPart.setFileName(temp.getName());//防止中文名称下客户端服务端编码不统一而乱码:
//            bodyPart.setFileName(MimeUtility.encodeText("what.txt"));multipart.addBodyPart(bodyPart);//附件添加}}message.setContent(multipart);Transport.send(message);} catch (Exception e) {e.printStackTrace();}}}

main函数:

public class Mail {public static void main(String[] args) {BeanFactory ad = new ClassPathXmlApplicationContext("spring.xml");MailSender mailSender = (MailSender) ad.getBean("mailSender");mailSender.sendMail("lingh***com",new String[]{"****cn"},"java mail待你查收!","<image src='https://www.baidu.com/img/dong_8f1d47bcb77d74a1e029d8cbb3b33854.gif'/><a herf='https://www.baidu.com'>百度</a>",null);}}
<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--引入扫描器 base-package为扫描范围并不会全部实例化,需使用注解@Repository(注解在类级别上)--><context:component-scan base-package="org.example"/></beans>

专题四:AOP

aop概念特点

主要用于日志记录,性能统计,安全控制,事务处理等方面,实现公共功能性的重复使用。
带来的好处:
1:解耦,降低模块间的耦合度(高内聚,低耦合)
2:提高代码的复用性。
3:提高系统的扩展性。

基本概念:

Joinpoint(连接点)
被拦截到的每个点,spring中指被拦截到的每个方法。一个连接点代表一个方法的执行。
Pointcut(切入点)
对连接点进行拦截的定义(匹配规则定义 规定拦截哪些方法。对哪些方法进行处理。)
Advice(通知)
拦截到每一个连接点即(每一个方法)后所要做的操作。
1,前置通知(前置增强)–before()执行方法前通知。
2,返回通知(返回增强)–afterReturn()方法正常结束返回后的通知。
3,异常抛出通知(异常抛出增强)–afterThrow()
4,最终通知–after 无论方法是否发生异常,均会执行该通知
5,环绕通知–around 包围一个连接点的通知,如方法调用。
环绕通知可以在方法调用前后完成自定义的行为。
Aspect(切面)
切入点与通知的结合,决定了切面的定义。切入点定义了要拦截哪些类的哪些方法。
通知则定义了拦截方法后要做什么,切面则是横切关注点的抽象。
Target(目标对象)
被代理的目标对象
Weave(织入)
将切面应用到目标对象并生成代理对象的这个过程。
Introduction(引入)
在不修改原有应用程序代码的情况下,在程序运行期为类动态添加方法或字段的过程。

aop注解实现

因为spring-context引入了aop,还需要在环境中引入aspect-jweaver。

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.9</version>
</dependency>

引用命名空间与xsd

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"

开启aop环境

<!--开启aop环境
-->
<aop:aspectj-autoproxy/>
/**定义切面类* 切入点* 通知*/
@Component
@Aspect
public class LogAspect {/**定义切入点* execution 执行匹配* 第一个* public|private|protected这三个访问符修饰的方法* ..*代表包以及子包下的所有类  *为通配符,可以为具体值* .*(..)代表包以及子包下的所有类的所有方法*/@Pointcut("execution(* org.example..*.myWife(..))")public void cut(){}@Before(value = "cut()")public void before(){System.out.println("今天来的人好多,请耐心等待。。");}@AfterReturning(value = "cut()")public void afterReturning(){System.out.println("婚礼结束,散场。。");}@After(value = "cut()")public void after(){System.out.println("虽然仪器坏了,照样进行。");}@AfterThrowing(value = "cut()",throwing = "e")public void afterThrowing(Exception e){System.out.println("仪器坏了,师傅快来修。"+e);
}@Around(value="cut()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object result = null;System.out.println("round方法开始执行。");result = pjp.proceed();System.out.println("round方法执行结束。");Object[] args = pjp.getArgs();for (Object arg : args) {System.out.println(arg);}System.out.println(pjp.getSignature());System.out.println(pjp.getTarget());return result;}
}
/*** 目标类*/
@Component
public class MyWedding {public void myWife(String prince,String princess){System.out.println(String.format("今天的新人婚礼,新郎是%s,新娘是%s。", prince,princess));}
}
public class AspectTest {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");MyWedding wedding = (MyWedding) ac.getBean("myWedding");
//        MyWedding wedding = new MyWedding();wedding.myWife("张三","李四");}
}

在上面程序中,要使用xml加载的bean才可以使用切面。
执行任意公共方法:
execution(public (…))
执行任意的set方法(set开头的):
execution(
set*(…))
执行com.xyz.service包下任意类的任意方法:
execution(* com.xyz.service..(…))
执行com.xyz.service包 以及子包下任意类的任意方法:
execution(* com.xyz.service….(…))

另外一种匹配方式:
匹配注解:
“@annotation(定义注解的路径)”
可以直接标注对哪些方法进行增强。不需要艰难地过滤。

//自定义一个注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {String name() default "";
}//切面类
@Pointcut("@annotation(org.example.aspect.MyAnno)")
public void cut(){}@Around(value="cut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {Object result = null;System.out.println("round方法开始执行。");result = pjp.proceed();System.out.println("round方法执行结束。");Object[] args = pjp.getArgs();for (Object arg : args) {System.out.println(arg);}System.out.println(pjp.getSignature());System.out.println(pjp.getTarget());//展示了如何获取自定义注解的属性:通过Signature的实现类接口//调用getMethod获取方法,再获取注解。//注解也是对象!MethodSignature siture = (MethodSignature) pjp.getSignature();Method method = siture.getMethod();MyAnno myAnno = method.getAnnotation(MyAnno.class);if(null != myAnno){System.out.println(myAnno.name());}return result;}//测试方法
public class AspectTest {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");MyWedding wedding = (MyWedding) ac.getBean("myWedding");
//        MyWedding wedding = new MyWedding();wedding.myWife("张三","李四");}
}

注解属性的使用可以简化编程,比如可以设置权限码之类的。

代理–静态代理实现

代理设计模式
目的:增强目标类的行为
静态代理实现的三要素:
1,接口(共同的行为)
2,目标类(被代理的角色)
3,代理类
与目标类实现共同的行为(与目标类实现同一接口)
增强目标类的行为
持有目标类的引用
例子:Marry为共同接口,下面一个toMarry的方法。
You是目标类,Marry接口的实现类。
MarryCompany是代理类,也实现了Marry这个接口,而且
此代理类持有You对象的引用,因此在MarryCompany的toMarry方法中
可以调用You的toMarry方法,增强You的行为。

public interface IMarry {void toMarry();
}
/**目标类*/
public class You implements IMarry{@Overridepublic void toMarry() {System.out.println("等了这么久,终于等到你。。。");}
}
/**代理类,代理目标类行为增强目标类的方法。*/
public class MarryCompany implements IMarry{private IMarry target;public MarryCompany(IMarry target) {this.target = target;}public void before(){System.out.println("婚礼庆典即将开始。");}public void after(){System.out.println("结婚快乐,早生贵子。");}@Overridepublic void toMarry() {//行为增强before();target.toMarry();//行为增强after();}
}
public class TestStaticProxy {public static void main(String[] args) {MarryCompany marryCompany = new MarryCompany(new You());marryCompany.toMarry();}
}

静态代理的特点:

1,程序运行前,需要应用程序制作代理角色
2,代理的目标类 类型固定。
3,缺陷:对于每一类接口,如果需要作代理,应用程序需要提供大量的代理类
随着应用程序的复杂度上升,代理类的数据越来越大,维护比较麻烦。

多线程是静态代理的应用

代理–动态代理实现–JDK实现

动态代理最明显特点:在程序运行期为目标类动态地创建代理角色。

实现方式:

1,JDK内部

要求目标类必须存在接口实现。目标类不存在接口实现,无法创建代理对象。

(代理类是跟目标类平级的,不能用目标类来转换对象)

public static Object newProxyInstance(ClassLoader loader, //因为是动态代理,需要加载器Class<?>[] interfaces,        //目标类所有实现的接口InvocationHandler h)   //一个接口,值钱的就是下面这个准重写方法。invoke(Object proxy,Method method,Object[] args)

返回指定接口的代理实例,该代理实例将方法调用分派给指定的调用处理程序。

二合一写法:

/*** 仅仅用于产生动态代理类并且实现InvokeHandler*/
public class JdkHandler implements InvocationHandler {//目标类private Object target;public JdkHandler(Object target) {this.target = target;}public Object getProxy(){/*1,类加载器2,目标类实现的所有接口数组3,实现类InvocationHandler接口的类实例*/return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}public void before(){System.out.println("婚礼庆典即将开始。");}public void after(){System.out.println("结婚快乐,早生贵子。");}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object result = null;//执行目标类的方法:result = method.invoke(target,args);after();return result;}
}

用接口来接收代理类。

public class TestDynamicProxyJdk {public static void main(String[] args) {JdkHandler jdkHandler = new JdkHandler(new You());//采用父类来接收参数IMarry dynamicProxy = (IMarry) jdkHandler.getProxy();dynamicProxy.toMarry();}
}
/**目标类*/
public class You implements IMarry{@Overridepublic void toMarry() {System.out.println("等了这么久,终于等到你。。。");}
}

目标类必须实现了接口。

public interface IMarry {void toMarry();
}

代理类与目标类不能相互转换。 因此JDK无法满足给没有接口实现的目标类做代理的需求。

代理–动态代理–CGLIB实现

对于目标类是否存在接口实现没有要求(继承思想)
代理类属于目标类的子类。因此目标类可以引用代理类。
引用环境

<dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>3.3.0</version>
</dependency>

通过Enhancer这个类来实现:
此类有个create方法,需要设置两个参数(superclass以及callback)
callback为一个接口,使用其实现接口MethodInterceptor。

public class CGLibHandler implements MethodInterceptor {private Object target;public CGLibHandler(Object target) {this.target = target;}public Object getProxy(){Enhancer enhancer = new Enhancer();//设置父类enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);//返回代理类return enhancer.create();}public void before(){System.out.println("婚礼庆典即将开始。");}public void after(){System.out.println("结婚快乐,早生贵子。");}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {Object result = null;before();result = methodProxy.invoke(target, objects);after();return result;}
}

用目标类You来接收动态代理。

public class TestDynamicProxyJdk {public static void main(String[] args) {CGLibHandler cgLibHandler = new CGLibHandler(new You());//获取动态代理You youproxy = (You) cgLibHandler.getProxy();//多态,执行子类方法youproxy.toMarry();}
}

JDK制作动态代理时,制作效率较高。
AOP内部实现原理是JDK+CGLib。如果目标类有接口实现,采用JDK,如果没有,使用CGLib。

专题五:定时任务

1:概述

二叉树:有多种类型,分为满二叉树与完全二叉树。完全二叉树是指除了最后一层,其他层都是满节点,且最后一层节点靠左。
堆:堆是一种完全二叉树,且任何一个节点都不大于(或者不小于)父节点的值。
小顶堆:完全二叉树且每一节点都不小于父节点的值。
堆的存取:存在数组里面,第一个数组元素不放值,这样下标除二得到父节点位置。存的时候存在最后面,然后上浮。取的时候取最上面的,然后将最后一个值填充到第一个,然后下沉。
定时任务用到小顶堆,每个节点存放一个任务,当任务量巨大时会耗性能。
时间轮:round型时间轮,依然会遍历每个数组。分层时间轮将月轮与天轮分开,方便简洁。
实现定时器的大概有几种方式,一个是JDK自带的timer。
Timer的使用:(单线程+小顶堆)

package com.hxh.timer;import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;/**** 问题是由单线程的任务阻塞引起的。* task.run()方法导致的,单线程任务阻塞导致。* 在run方法中使用多线程,另起线程,线程池即可。** 对系统时间比较敏感,任务调度基于绝对时间。** TaskQueue小顶堆*/
public class TimerTest {public static void main(String[] args) {Timer timer = new Timer();//任务启动for (int i=0;i<2;i++){TimerTask timerTask =new FooTimerTask("foo"+i);//中间参数,立即启动
//            timer.schedule(timerTask,new Date(),2000);//任务添加,真正的执行时间取决于上一个任务执行的时间。//任务超时时,schecule存在丢任务的风险,执行周期小于(时间推迟了就是丢任务了。)//任务超时时,scheduleAtFixedRate严格按照period执行。但是会导致任务执行混乱掉。timer.schedule(timerTask,new Date(),8000);//优先使用这个函数,多个任务执行时间小于period}}
}
class FooTimerTask extends TimerTask{private String name;public FooTimerTask(String name) {this.name = name;}@Overridepublic void run() {try {System.out.println("name ---> "+name+" ,startTime"+new Date());Thread.sleep(3000);System.out.println("name ---> "+name+" ,endTime"+new Date());} catch (InterruptedException e) {e.printStackTrace();}}
}

线程池的使用(多线程+小顶堆)

package com.hxh.pool;import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** 定时任务线程池* 在timer的基础上做了优化**小顶堆* leader-follower模式:只有leader线程执行任务,* 其他follower线程等待变为leader线程,避免没必要的唤醒与阻塞操作。** 任务同时启动,如果任务超时间隔周期,则任务结束后会立即启动。**/
public class ScheduleThreadPoolTest {public static void main(String[] args) {ScheduledExecutorService scheduledExecutorPool = Executors.newScheduledThreadPool(5);for (int i=0;i<2;i++){//需要一个Runnable command//.schedule未传间隔时间,只执行一次,需要用到//.scheduleAtFixedRate可设置间隔时间scheduledExecutorPool.scheduleAtFixedRate(new Task("masaka--"+i),0,4, TimeUnit.SECONDS);}}}class Task implements Runnable{private String name;public Task(String name) {this.name = name;}@Overridepublic void run() {try {System.out.println("name ---> "+name+" ,startTime"+new Date());Thread.sleep(3000);System.out.println("name ---> "+name+" ,endTime"+new Date());} catch (InterruptedException e) {e.printStackTrace();}}
}
2:quartz

并发任务,且每次创建一个新的job实例。可以规避并发访问的问题。

@DisallowConcurrentExecution

这个注解无视执行触发时间间隔,只有j每次的job执行完毕后,下一个才开始。

@PersistJobDataAfterExecution

让JobData持久化,可以递增一些data,这两个注解标注在Job任务上,但是后者只对jobDetail里的.usingJobData有效。如果一个任务不是持久化的,则当没有触发器关联它的时候,Quartz会从schedule中删除它。

trigger里的usingJobData会覆盖jobDetail里的同key值data。

trigger的其他内容:

同时触发的trigger之间才会比较优先级,如果trigger是可恢复的,在恢复后再调度时,优先级不变。

misfire错过触发:判断misfire的条件:1,job达到触发时间没有被执行;2,被执行的延迟时间超过了Quartz配置的misfire Threshold。

3:时间解析
//如何将UTC统一时间规范化。
String timmi = "2020-12-22T06:18:55.592Z";
SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date1 = df1.parse(timmi);
String date2 = df2.format(date1);
System.out.println(date1);//Tue Dec 22 06:18:55 CST 2020
System.out.println(date2);//2020-12-22 06:18:55
System.out.println(date1.getTime());//long 1608589135592
Timestamp timestamp = new Timestamp(date1.getTime());//根据long类型建立实例
System.out.println(timestamp.getTime());//输出1608589135592
System.out.println(timestamp.toLocalDateTime());//2020-12-22T06:18:55.592
System.out.println(timestamp);//2020-12-22 06:18:55.592
System.out.println(timestamp.toString());//自身toString长这个样子。2020-12-22 06:18:55.592String hxh1 = Long.toString(1608589135592L);
String hxh2 = String.valueOf(1608589135592L);//*******************************************
//项目使用:
String timmi = "2020-12-22T06:18:55.592Z";
SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date1 = df1.parse(timmi);
Timestamp timestamp = new Timestamp(date1.getTime());
//再把timestamp插入到数据库。
//将时间的日期插入到sql中。
java.sql.Date sql_date = new java.sql.Date(date1.getTime());
System.out.println(sql_date);//输出2020-12-22

Spring学习(下)相关推荐

  1. spring学习12 -Spring 框架模块以及面试常见问题注解等

    以下为spring常见面试问题: 1.Spring 框架中都用到了哪些设计模式? Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的: 代理模式-在AOP和remoting中被用的比较 ...

  2. Spring Security 实战:Spring Boot 下的自动配置

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「码农小胖哥」 1. 前言 我们在前几篇 ...

  3. SpringBoot的全局异常处理的优雅吃法!要进来学习下吗

    SpringBoot的全局异常处理的优雅吃法!要进来学习下吗 SpringBoot全局异常准备 开发准备 环境要求 JDK :1.8 SpringBoot :1.5.17.RELEASE 首先还是Ma ...

  4. Spring学习总结三

    Spring框架JdbcTemplate与事务 Spring学习总结三 0.需要的jar包 1.JdbcTemplate模板 1.1.JdbcTemplateAPI的操作 1.1.1.User类 1. ...

  5. Spring学习总结二

    Spring框架的代理与AOP.AspectJ Spring学习总结二 0.在理解什么是AOP之前的一些话 1.什么是AOP 2.AOP的重要概念 3.代理模式 3.1.静态代理 3.2.动态代理 3 ...

  6. Spring学习总结一

    Spring框架IoC与DI思想及应用 Spring学习总结一 1.Spring是什么 2.Spring的优点 2.1.关键概念 2.2.Spring的优点 3.Spring的架构图 3.1.核心容器 ...

  7. Spring学习(八)AOP详解

    本文借鉴:Spring学习 一.一个例子 在上面的例子中,包租婆的核心业务就是签合同,收房租,那么这就够了,灰色框起来的部分都是重复且边缘的事,交给中介商就好了,这就是 AOP 的一个思想:让关注点代 ...

  8. Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】...

    本文借鉴:Spring学习,@Bean 的用法(特此感谢!) 自动装配 1.歧义性 我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器 ...

  9. Spring学习(六)bean装配详解之 【通过注解装配 Bean】【基础配置方式】

    本文借鉴:Spring学习(特此感谢!) 通过注解装配 Bean 1.前言 优势 1.可以减少 XML 的配置,当配置项多的时候,XML配置过多会导致项目臃肿难以维护 2.功能更加强大,既能实现 XM ...

  10. Spring学习(五)bean装配详解之 【XML方式配置】

    本文借鉴:Spring学习(特此感谢!) 一.配置Bean的方式及选择 配置方式 在 XML 文件中显式配置 在 Java 的接口和类中实现配置 隐式 Bean 的发现机制和自动装配原则 方式选择的原 ...

最新文章

  1. C++ 简单读写文本文件、统计文件的行数、读取文件数据到数组
  2. 总结一下这几天操作符的学习心得
  3. python元组类型_什么是python元组数据类型
  4. 详解Python的*args和 **kwargs
  5. 1.3、Bootstrap V4自学之路------起步---浏览器支持
  6. 单臂路由实验(子接口的使用)
  7. 《Linux性能及调优指南》 Linux进程管理
  8. 西门子的十一位CEO
  9. SpringMVC 工作原理
  10. VS的Qt界面预览和QtCreator的界面预览快捷键
  11. switch好玩吗_Switch上有什么好玩的游戏_第三方游戏有什么值得推荐的
  12. 例题 9-2 巴比伦塔(The Tower of Babylon, UVa 437)
  13. imagemagick使用_使用ImageMagick裁剪和调整图像大小
  14. Json转对象失败:No suitable constructor found for type [simple type, class com.test.faster.domain.respons
  15. android AMS
  16. MySQL 教程(一)
  17. 智慧家庭产业链及典型企业
  18. 查看服务器所有进程信息,怎么查看服务器上的所有进程
  19. 核心微生物分析_基因测序找出肠道核心微生物群
  20. P1719 最大加权矩形(二维dp)

热门文章

  1. 三星 android截屏快捷键是什么手机,三星手机如何快速截屏?两种快速截图方法教给你!...
  2. (自用)Linux系统彻底卸载MySQL数据库
  3. emmx文件用什么软件打开电脑_emmx文件怎么打开
  4. vos3000 2.1.1.5 安装包及注册机【电销电话机器人源码私有云部署 www.ruikesoft.com 正版授权 抵制盗版】
  5. Vulkan----Mac环境搭建
  6. vue 项目路由配置
  7. bat批处理脚本命令大全
  8. 国产自主产权,跨平台组态软件
  9. Abaqus安装在lincense server1出错
  10. ABAQUS2021界面改成中文