首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,649 阅读
2
Mac打印机设置黑白打印
5,043 阅读
3
修改elementUI中el-table树形结构图标
4,946 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,705 阅读
5
intelliJ Idea 2022.2.X破解
4,459 阅读
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Vue
Mac
Spring Cloud
MyBatis
WordPress
MacOS
asp.net
Element UI
Nacos
MySQL
.Net
Spring Cloud Alibaba
Mybatis-Plus
Typecho
jQuery
Java Script
IntelliJ IDEA
微信小程序
Laughing
累计撰写
629
篇文章
累计收到
1,421
条评论
首页
栏目
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
友链
广告合作
壁纸
美女主播
搜索到
629
篇与
的结果
2021-12-18
SpringBoot JPA自动设置创建时间、修改时间
JPA提供了审计功能,用于设置创建者、创建时间、修改者、修改时间等参数。创建时间、修改时间很好理解,就是当前时间,但是创建者、修改者一般都是通过上下文信息获取的,由于我这边是接口里面使用,未使用创建者、修改者,所以先介绍一下创建时间、修改时间的使用。添加依赖那些巴拉巴拉的就不啰嗦。创建实体@Getter @Setter @ToString @Entity @Table(name = "ARAPDiscountRecord") @EntityListeners(AuditingEntityListener.class) public class ARAPDiscountRecordEntity implements Serializable { @CreatedDate @Column(name = "timestamp_createdon") private Timestamp timestampCreatedon; @LastModifiedDate @Column(name = "timestamp_lastchangedon") private Timestamp timestampLastchangedon; }@CreatedDate注解用于标识创建时间。@LastModifiedDate注解用于标识修改时间。实体类添加@EntityListeners(AuditingEntityListener.class)标识启动审计。启动审计再启用或者配置类上添加@EnableJpaAuditing启动审计。@EnableJpaAuditing @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }这样的话,每次创建数据,系统会自动赋值timestampCreatedon列,修改数据时,系统会自动赋值timestampLastchangedon字段。
2021年12月18日
1,527 阅读
0 评论
0 点赞
2021-12-12
Spring Boot中ThreadLocal踩坑
ThreadLocal作用ThreadLocal的作用:用来存当前线程的局部变量,不同线程间互不干扰。拿完数据记得需要移除数据,不然JVM不会将ThreadLocal回收(可能还会被引用),多了就会出现内存泄漏的情况。解析ThreadLocal类ThreadLocal包含几个方法:public T get() { } public void set(T value) { } public void remove() { } protected T initialValue() { }T get()get()方法是用来获取ThreadLocal在当前线程中保存的变量副本set(T value)set()用来设置当前线程中变量的副本void remove()remove()用来移除当前线程中变量的副本T initialValue()initialValue()是一个protected方法,一般是用来在使用时进行重写的,它是一个延迟加载方法。ThreadLocal变量污染ThreadLocal会在每个线程存储一个副本,但是如果我们使用的是比如Tomcat,Tomcat自身会维护一个线程池,线程结束后,并不会马上销毁,而是会重新进入线程池,下次有请求时,有可能会复用当前线程,如果我们每次使用ThreadLocal之前,没有进行Set(T value),那么就有可能导致不同线程之间变量污染,比如下面的代码@RestController @RequestMapping(value = "book") @Slf4j public class BookController { private static final ThreadLocal<String> THREAD_LOCAL_TEST = new ThreadLocal<>(); @Resource private IBookService bookService; /** * 构造函数 */ public BookController() { log.info("构造函数,此时bookService :" + bookService); } @PostConstruct public void init() { log.info("PostConstruct,此时bookService :" + bookService); } @PreDestroy public void destroy() { log.info("PreDestroy"); } @GetMapping(value = "set") public void set() { if (StringUtils.isEmpty(THREAD_LOCAL_TEST.get())) { THREAD_LOCAL_TEST.set(UUID.randomUUID().toString()); } } @GetMapping(value = "search") public List<Book> search() { log.error(THREAD_LOCAL_TEST.get()); return bookService.search(); } }使用jmeter进行请求,可以看到同一线程,输出的内容永远不会发生改变。可以在内次使用之前进行set(T value),但是set(T value)可能会导致内存无法释放。ThreadLocal可能导致的内存泄露ThreadLocal为了避免内存泄露,不仅使用了弱引用维护key,还会在每个操作上检查key是否被回收,进而再回收value。但是从中也可以看到,ThreadLocal并不能100%保证不发生内存泄漏。比如,很不幸的,你的get()方法总是访问固定几个一直存在的ThreadLocal,那么清理动作就不会执行,如果你没有机会调用set()和remove(),那么这个内存泄漏依然会发生。一个良好的习惯依然是:当你不需要这个ThreadLocal变量时,主动调用remove(),这样对整个系统是有好处的。@RestController @RequestMapping(value = "book") @Slf4j public class BookController { private static final ThreadLocal<String> THREAD_LOCAL_TEST = new ThreadLocal<>(); @Resource private IBookService bookService; /** * 构造函数 */ public BookController() { log.info("构造函数,此时bookService :" + bookService); } @PostConstruct public void init() { log.info("PostConstruct,此时bookService :" + bookService); } @PreDestroy public void destroy() { log.info("PreDestroy"); } @GetMapping(value = "set") public void set() { THREAD_LOCAL_TEST.set(UUID.randomUUID().toString()); } @GetMapping(value = "search") public List<Book> search() { log.error(THREAD_LOCAL_TEST.get()); THREAD_LOCAL_TEST.remove(); return bookService.search(); } }ThreadLocal与局部变量局部变量和ThreadLocal起到的作用是一样的,保证了并发环境下数据的安全性。那就是说,完全可以用局部变量来代替ThreadLocal咯?This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).翻译过来 ThreadLocal提供的是一种线程局部变量。这些变量不同于其它变量的点在于每个线程在获取变量的时候,都拥有它自己相对独立的变量初始化拷贝。ThreadLocal的实例一般是私有静态的,可以做到与一个线程绑定某一种状态。所以就这段话而言,我们知道ThreadLocal不是为了满足多线程安全而开发出来的,因为局部变量已经足够安全。ThreadLocal是为了方便线程处理自己的某种状态。 可以看到ThreadLocal实例化所处的位置,是一个线程共有区域。好比一个银行和个人,我们可以把钱存在银行,也可以把钱存在家。存在家里的钱是局部变量,仅供个人使用;存在银行里的钱也不是说可以让别人随便使用,只有我们以个人身份去获取才能得到。所以说ThreadLocal封装的变量我们是在外面某个区域保存了处于我们个人的一个状态,只允许我们自己去访问和修改的状态。
2021年12月12日
1,893 阅读
0 评论
0 点赞
2021-12-10
log4j漏洞解决办法
漏洞详情Apache Log4j2是一款优秀的Java日志框架。2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。漏洞利用无需特殊配置,经阿里云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。阿里云应急响应中心提醒 Apache Log4j2 用户尽快采取安全措施阻止漏洞攻击。受影响的版本所有Apache Log4j 2.*系列版本:Apache Log4j 2.0-alpha1 – Apache Log4j 2.8.1不受影响的版本Apache Log4j 2.8.2修复及建议尽快通过参考链接中官网地址升级到最新版本:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2配置网络防火墙,禁止系统主动外连网络,包含不限于DNS、TCP/IP、ICMP。升级已知受影响的应用及组件,如srping-boot-strater-log4j2、ApacheSolr、Apache Flink、Apache Druid。紧急加固缓解措施:①设置参数:log4j2.formatMsgNoLookups=True②修改JVM参数:-Dlog4j2.formatMsgNoLookups=true③系统环境变量:FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS设置为true④禁止 log4j2 所在服务器外连
2021年12月10日
2,007 阅读
0 评论
0 点赞
2021-12-09
Parallels Desktop 虚拟机 v17.1.1 (51537)(含win10-win11镜像)
Parallels Desktop 虚拟机 v17.1.1 (51537)(含win10-win11镜像)
2021年12月09日
1,034 阅读
0 评论
0 点赞
2021-12-05
@SpringBootApplication标注非引导类
一般情况下,@SpringBootApplication一般都是标注在项目引导类上。像下面这样:@Slf4j @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoConfiguration.class, args); } }但是@SpringBootApplication一定要标注到引导类上吗?答案是否定的。我们可以将@SpringBootApplication标注到任意的类上。比如我们增加以下类package cc.lisen.demo.config; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoConfiguration { }然后改造引导类@Slf4j public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoConfiguration.class, args); } }再次运行项目,可以发现项目可以正常运行但是如果我们访问我们的接口,会发现提示404注意我们DemoConfiguration所在的包cc.lisen.demo.config,@SpringBootApplication只会扫描当前包及下级包,所以,我们的接口它扫描不到,就提示404。如果希望我们其他的类被扫描到,我们就需要添加scanBasePackages属性。package cc.lisen.demo.config; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = {"cc.lisen.demo"}) public class DemoConfiguration { }重启项目,在访问接口,发现能正常访问
2021年12月05日
978 阅读
0 评论
0 点赞
2021-12-05
理解SpringBoot 中的@AliasFor注解
感觉Spring Boot中的@AliasFor注解是一个既熟悉又陌生的注解。说熟悉,是因为我们经常使用的比如@Service、@RestController、@Repository甚至@SpringBootApplication中都有他们的身影。说陌生,是因为其实从来没有真正用过这个注解。@AliasFor注解有两个作用:定义一个注解中的两个属性互为别名。桥接其他注解的属性。一、定义一个注解中的两个属性互为别名。我们以ComponentScan注解为例,先来看下ComponentScan的定义@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class; ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT; String resourcePattern() default "**/*.class"; boolean useDefaultFilters() default true; ComponentScan.Filter[] includeFilters() default {}; ComponentScan.Filter[] excludeFilters() default {}; boolean lazyInit() default false; @Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Filter { FilterType type() default FilterType.ANNOTATION; @AliasFor("classes") Class<?>[] value() default {}; @AliasFor("value") Class<?>[] classes() default {}; String[] pattern() default {}; } }以上代码,我们关注点在于 @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {};这段代码,代表着,在ComponentScan注解中,basePackages属性与value是一样的,可以相互调用。我们可以测试一下@ComponentScan(basePackages = {"cc.lisen.demo"}) @Component @EnableAutoConfiguration @Slf4j public class DemoApplication { public static void main(String[] args) { ComponentScan componentScan = AnnotatedElementUtils.getMergedAnnotation(DemoApplication.class, ComponentScan.class); assert componentScan != null; System.out.println(Arrays.toString(componentScan.basePackages())); System.out.println(Arrays.toString(componentScan.value())); SpringApplication.run(DemoApplication.class, args); } }二、桥接其他注解的属性这次,我们看下@Service的代码@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Service { @AliasFor( annotation = Component.class ) String value() default ""; }可以看到,@Service将value属性,桥接到了@Component注解的value属性。@ComponentScan(basePackages = {"cc.lisen.demo"}) @Component @EnableAutoConfiguration @Slf4j public class DemoApplication { public static void main(String[] args) { Component component = AnnotatedElementUtils.getMergedAnnotation(BookService.class, Component.class); assert component != null; System.out.println(component.value()); SpringApplication.run(DemoApplication.class, args); } }
2021年12月05日
1,132 阅读
0 评论
1 点赞
2021-11-23
JS !(非运算)详解
逻辑非运算!是布尔取反操作(NOT)。作为一元运算符,直接放在操作数之前,把操作数的值转换为布尔值,然后取反并返回。下面是一些特殊操作数的逻辑非运算返回值。console.log( ! {} ); //如果操作数是对象,则返回false console.log( ! 0 ); //如果操作数是0,则返回true console.log( ! (n = 5)); //如果操作数是非零的任何数字,则返回false console.log( ! null ); //如果操作数是null,则返回true console.log( ! NaN ); //如果操作数是NaN,则返回true console.log( ! Infinity ); //如果操作数是Infinity,则返回false console.log( ! ( - Infinity )); //如果操作数是-Infinity,则返回false console.log( ! undefined ); //如果操作数是undefined,则返回true如果对操作数执行两次逻辑非运算操作,就相当于把操作数转换为布尔值。console.log( ! 0 ); //返回true console.log( ! ! 0 ); //返回false逻辑与和逻辑或运算的返回值不必是布尔值,但是逻辑非运算的返回值一定是布尔值。
2021年11月23日
1,023 阅读
0 评论
0 点赞
2021-11-21
Mac系统更新提示及设置图标上的小红点
Mac系统每隔一段时间就会自动提示更新,系统更新图标上会显示红色的更新提示,在通知中心也会经常弹出通知,有强迫症的看着就很烦。取消系统更新提示1、打开【系统偏好设置】— 点击【软件更新】2、取消选择【自动保持我的Mac最新】3、然后点击【高级】按钮,取消所有的勾选取消设置图标上的小红点 如果系统已经检测到了更新,此时设置节点上会有小红点 我们可以通过以下方式取消掉。 打开终端,依次执行以下代码defaults write com.apple.systempreferences AttentionPrefBundleIDs 0 Killall Dock 此时,设置上的小红点就消失了。
2021年11月21日
2,001 阅读
0 评论
1 点赞
2021-11-17
小书匠不同终端数据同步配置
小书匠确实是个不错的软件,免费版的就支持码云、GitHub等存储,同时也支持阿里、七牛等图床服务 对我个人而言,我比较看重一款软件的终端兼容性。因为公司电脑是Win,家里用Mac,手机是一加,平板是IPad,所以多终端数据同步成了必要的要求。前置条件 小书匠官方推荐使用Couch DB数据库,我们这里也使用Couch DB数据库,如果不会安装的,可以参考centOS 安装Couch DB数据库小红书配置 打开数据标签,找到同步页签 输入数据库连接信息、用户名、密码如下 这样就完成配置了,在不同终端登录同一个小书匠的账户,数据便能自动同步。
2021年11月17日
1,240 阅读
0 评论
1 点赞
2021-11-17
centOS 安装Couch DB数据库
最近发现一个神级笔记软件--小书匠,但是有个问题,就是虽然支持不同终端同步,但是需要有自己的数据库。软件下载及安装sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://couchdb.apache.org/repo/couchdb.repo sudo yum install -y couchdb修改配置文件 /opt/couchdb/etc/local.ini在 [chttpd] 节点里, 把 ;bind_address = 127.0.0.1 修改成 bind_address = 0.0.0.0。在 [chttpd] 节点位置,也就是刚才 bind_address 下面添加一行 require_valid_user = true.在 [admins] 节点里,将 ;admin = mysecretpassword 修改为 admin = xiaoshujiang , 其中 admin 为用户名, xiaoshujiang为密码,可以根据自己需要设定在 [couch_httpd_auth] 节点里,将 ; require_valid_user = false 修改为 require_valid_user = true。在 [httpd] 节点下,添加一行 enable_cors = true.在文件的结尾添加下面的内容[cors] origins = * credentials = true headers = accept, authorization, content-type, origin, referer methods = GET, PUT, POST, HEAD, DELETE启动修改完配置文件后,通过命令行执行 service couchdb start 启动就可以了访问访问 http://服务器ip地址:5984/_utils/index.html, 浏览器会弹出用户名认证窗口,输入刚才在配置文件里使用的用户名(admin)和密码(xiaoshujiang),能够正常访问就表示数据库搭建完成,可以接下来小书匠编辑器配置的操作了。这里需要注意的是,如果您的服务器开启了端口访问限制,记得取消对 5984 端口的限制访问。
2021年11月17日
1,132 阅读
0 评论
0 点赞
2021-11-14
Spring Boot使用Jetty或Undertow替换默认的Tomcat嵌入式容器
Spring Boot切换嵌入式容器的方式非常简单,只需两步,第一步排除Tomcat依赖,第二步,添加Jetty或者Undertow依赖。排除默认的Tomcat依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!--排除Tomcat--> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> 添加Jetty依赖如果使用Jetty作为嵌入式容器,我们添加如下依赖。<!--添加Jetty依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency>添加Undertow依赖如果使用Undertow作为嵌入式容器,我们可以添加如下依赖<!--添加Undertow依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>
2021年11月14日
986 阅读
0 评论
0 点赞
2021-11-14
java类型转换的一些问题及处理
最近在项目上被类型转换坑了不少。特以此文做一下记录。问题出在哪以前在项目开发的时候,在数据访问层,基本上是使用MyBatis,偶尔使用JPA,不管哪种方式,我们数据访问都是建立在实体之上的(极少数情况下也会使用Map,但是这种情况是比较特殊的。目前公司的开发平台,数据访问层,统一通过平台封装的BQL进行,问题就出现在这个封装的BQL上,它返回的数据类型是List<Map<String,Object>>类型,这个东西看似灵活(因为是Map,另外还是Object的泛型),既然返回的是Object类型,那就涉及到类型转换的问题。这种Object的弱类型,也给我们创建实体制作了障碍,比如我们一个实体可能有Integer类型、String类型等等。但是,我们总不能把实体全部创建层Object类型的。进一步的问题截止到目前,我们发现的第一个问题就是Object需要转换成具体的类型。紧接着,我们面临着第二个问题,就是我们通过BQL这个东西建表的时候,我们选择的比如是Integer类型(整型),我们会发现,在postgre数据库中,创建的类型确实是Integer,但是在Oracle中创建的是Number类型,然后我们在用BQL取数的时候,在postgre数据库中,取出的Object是Integer,但是在Oracle中取出的Object确实BigDecimal类型,这就让人比较懵逼了。我在创建实体的时候,到底是用Integer还是用BigDecimal呢。如何定义类型通过上面分析,我们可以确定的是,我们需要的是Integer而不是BigDecimal。所以,我们在创建实体时,创建的是一个Integer类型的。如何进行类型转换以上,便引出了我们如何进行类型转换的话题。在Java中如何进行类型转换呢,我们以Integer类型为例,常见的方式可能就以下三种。(Integer)obj:将obj转换成Integer类型,这种obj可以是Object类型。Integer.parseInt(obj):将字符串类型的obj转成对应的数值。Integer.valueOf(obj):将字符串类型的obj转成对应的数值。那么这三种方法有啥区别呢,我们以以下代码为例Object str123 = new BigDecimal("123"); int int123 = (int) str123; int parseInt = Integer.parseInt(str123.toString()); Integer valueOf = Integer.valueOf(str123.toString()); System.out.println(int123); System.out.println(parseInt); System.out.println(valueOf);以上代码,idea不会给出任何的错误提示但是我们运行时,会发现int int123 = (int) str123;这行代码会报错因为str123实际是BigDecimal类型所以(Integer)报错了。区别一:(Integer)只能转换相同的类型,否则会报错。我们跳转代码,可以查看Integer.parseInt()和Integer.valueOf()通过上面截图,我们可以看到Integer.parseInt()和Integer.valueOf()的区别。Integer.parseInt()返回的是基本类型int,Integer.valueOf()返回的是对象类型Integer。区别二:Integer.parseInt()返回的是基本类型int,Integer.valueOf()返回的是对象类型Integer。
2021年11月14日
860 阅读
0 评论
1 点赞
1
...
17
18
19
...
53