谈谈自己对AOP以及动态代理的理解 还有 数据库时区的问题

1.AOP 和动态代理与事务

AOP  大家已经很熟悉了吧,Spring核心思想之一,面向切面编程。

今天给大家说说aop,他就是对 IOC容器里的对象,进行方法的增强。

注意,他只能增强 IOC容器内的bean,通过自己new出来的不能被代理,

原理就是,有接口就是JDKproxy,没有接口就是CGLIB。

自定义切面,切的注解,也是,注解标在IOC容器里的对象,才能够代理它,Spring管理的对象嘛。才支持被AOP的权利,原理就是,看看IOC容器中有没有这个类,或者有没有被注解标记的方法,有就创建代理类去代理当前类,最后通过依赖注入到 别的对象属性中  供它使用。

再说说事务 ,Spring声明式事务也是通过AOP实现的。

如果事务AOP 和 环绕执行增强,共同切了一个方法,那么谁代理谁呢?

正确答案是,经过测试,不管注解摆放的顺序,都是Transaction在代理  增强类。

简单来说,你环绕增强执行完真实对象的方法之后抛了异常, 是在Spring事务代理范围之内的

会回滚事务!

所以事务的代理是最后代理的,里面不管你加了几层 AOP 都是最后 加的事务代理,然后抛异常肯定能够回滚。

2.数据库时区

当使用 Mysql  8.0的时候。我们配置Springboot yml配置文件的时候,需要配置时区,这里的时区一定要和数据库配置一样的时区,要不然数据库使用UTC时区,Java默认时区为GMT+8 东八区,

会使数据库时间类型的传到Java上面来,小时+8,导致时间不一致。  

和Jackson原理一样,在spingboot 接口controller 转JSON到前端,默认以格林威治时间,转化,所以会 减8,在yml文件配置Jackson 时区配置了 GMT+8 保证格式与 Java默认时区一致,就不会在转换时区的时候,被增加或减少,导致不必要的麻烦。

总结,数据库时区和Java时区和Jackson时区保证一致就不会导致时间不一致的现象发生。

但是字符串不会受时区的印象,比如mybatis plus 使用时间当参数,你穿字符串的话,是不会被 时区解析,直接当字符串传入SQL,然后进入数据库,是原样的。

在数据库转换时区,是在那一步,是在SQL预编译,将Date转化为时间戳,然后转化为java.sql.Date 类的时候,会以yml文件url后面的时区,进行时区的转化,时间戳就是格林威治到现在的毫秒值,然后根据不同时区,转化为不同的日期值嘛,然后转化到UTC的话,那就是正常GMT+8时区 -8小时,就是UTC,这就是为什么我查出来的时间,比我放入字符串的时间,多8小时,是因为它传上来的时间戳,按照GMT+8时区,把原来的时间先加8小时,才能和Java时区对上。但是你设置数据库时区为GMT+8,时区一致了,就不会有时区转化了。

转换原理:

前端到controller:没规定时区,就是UTC ,然后转化为时间戳,放到 Java里,根据Java时区,是GMT+8所以Java时间就多了8小时,然后如果给了时区和GMT+8一致 ,先减8 转化为时间戳,到Java 转化为 GMT+8在加回来。

数据库到Java同理。从Java Date转化时间戳,少了8小时,然后UTC的时区,转化为数据库Java.sql.Date,他不加回来了,这就是为什么少了8小时

数据库传上来 Java.sql.Date类型,你设置时区为UTC,他不会减8小时变时间戳,然后时间戳转化GMT+8又加了8小时,这就是为什么时间多了8个小时的原因。

你可能感兴趣的:(自我理解,java,开发语言)