首页
友情链接
精美壁纸
给我留言
更多
关于我
Search
1
uniapp Click点击事件冲突解决
4,587 阅读
2
【插件】UNI APP 实现商米打印机功能支持T1,T2,V2机型
4,001 阅读
3
【测试可用】个人码免签支付系统源码/免签支付系统/微信支付平台
2,040 阅读
4
windows10下docker:给已存在的容器添加端口映射的方法
1,252 阅读
5
Java Validation参数校验注解使用
1,234 阅读
Java
Spring Boot
Spring Mvc
Java基础
进阶知识
前端
uniapp
小程序/公众号
JavaScript
HTML/CSS
Vue
PHP
开源软件
商城
营销工具
开发工具
视频/教程
Discuz主题/插件
typecho主题/插件
SEO杂谈
数据库
MongoDB
MySQL
Redis
单片机
概念说明
电路相关
Python
devops
docker
k8s
linux
职场杂谈
登录
/
注册
Search
标签搜索
python
mysql
人人商城
php
java
docker
typecho
插件
微擎
seo
spring boot
discuz
队列
uni-app
phpcms
教程视频
开源系统
源码
工具
css
哈根达斯
累计撰写
108
篇文章
累计收到
161
条评论
首页
栏目
Java
Spring Boot
Spring Mvc
Java基础
进阶知识
前端
uniapp
小程序/公众号
JavaScript
HTML/CSS
Vue
PHP
开源软件
商城
营销工具
开发工具
视频/教程
Discuz主题/插件
typecho主题/插件
SEO杂谈
数据库
MongoDB
MySQL
Redis
单片机
概念说明
电路相关
Python
devops
docker
k8s
linux
职场杂谈
页面
友情链接
精美壁纸
给我留言
关于我
搜索到
22
篇与
Java
的结果
2022-11-25
Maven中设置依赖引用第三方jar,并打包部署
目录有很多jar包我们在maven远程仓库中无法下载时,需要在项目中添加依赖怎么处理呢?第一步:将jar包放到放到项目resource下lib文件夹中,如无此文件夹,请先创建,再将jar放进去<!--以下内存根据实际情况自定义填写--> <dependency> <groupId>org.demo</groupId> <artifactId>demo-core</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/libs/demo.jar</systemPath> </dependency> 第二步:添加完成后我们此时ide已经可以正常的进行获取包内的文件,并进行开发,但是我们打包后发现找不到类,此时我们需要在插件配置项添加如下代码. <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--解决本地jar包打不进jar的问题--> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> </plugin> </plugins> 我们在重新打包使用 mvn clean package -Dmaven.test.skip=true,重新运行后发现已经可以正常了
2022年11月25日
97 阅读
0 评论
0 点赞
2022-04-16
JRebel是一套JavaEE开发工具
简介JRebel是一套JavaEE开发工具。Jrebel 可快速实现热部署,节省了大量重启时间,提高了个人开发效率。JRebel是一款JAVA虚拟机插件,它使得JAVA程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。JRebel使你能即时分别看到代码、类和资源的变化,你可以一个个地上传而不是一次性全部部署。当程序员在开发环境中对任何一个类或者资源作出修改的时候,这个变化会直接反应在部署好的应用程序上,从而跳过了构建和部署的过程,可以省去大量的部署用的时间。JRebel是一款JVM插件,它使得Java代码修改后不用重启系统,立即生效。IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,浪费时间浪费生命。目前对于idea热部署最好的解决方案就是安装JRebel插件。安装第一步:安装插件第二步:在线GUID地址https://www.guidgen.com/如果失效刷新GUID替换就可以!服务器地址:https://jrebel.qekang.com/{GUID}第三步:打开jrebel 如下所示面板,选择Connect to online licensing service安装成功之后就可以通过JRebel启动项目。这样修改完Java代码后,就可以通过快捷键 Ctrl+shift+F9 而不再需要重启站点这样繁琐浪费时间的操作了。相关设置破解完成后的样子设置成离线工作模式设置自动编译要想实现热部署,首先需要对Intellij按如下进行设置:由于JRebel是实时监控class文件的变化来实现热部署的,所以在idea环境下需要打开自动变异功能才能实现随时修改,随时生效。打开运行时编译设置compiler.automake.allow.when.app.running快捷键ctrl+shift+A,搜索:registry或者按快捷键 Ctrl+Shift+Alt+/ ,选择 Registry使用运行项目时要点击图中红框中的按钮,即可运行:第一个按钮是Run,第二个按钮是Debug。修改代码(只测试了Java代码的修改)后,按快捷键 Ctrl + Shift + F9,运行后会提示有变化是否重新加载,选yes。完成加载以后,就已经实现了热更新效果。作者:想长高的美男子链接:https://www.jianshu.com/p/fa1e867f55d8来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2022年04月16日
118 阅读
0 评论
0 点赞
2021-09-01
Java Stream 流式编程
前言在很多语言中都会有 map、reduce、filter 等高阶函数对应的流式编程。那么对应 Java 中的功能就是 Stream 操作。// 生成 1357 并打印Arrays.stream(new int[] {1, 3, 5, 7}).forEach(System.out::println);复制代码所以今天就整理一下关于 Java Stream 流式编程。关于 StreamStream 是 Java8 添加的一个新的抽象称为流,可以让你以一种声明的方式处理数据。Stream 可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。Stream 流的操作是以管道的方式串起来的。管道以数据源开始,包含若干个中间操作,最终以终点操作结束。简单使用下面介绍一下在 Java 中简单的使用:Map Filter ReduceList<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9); // 求和 // Integer sumResult = list.stream().reduce(0, (a, b) -> a + b); Integer sumResult = list.stream().reduce(0, Integer::sum); // 45 System.out.println(sumResult); // 遍历数组 list.forEach(System.out::print); // 123456789 System.out.println(); // 返回数组元素的平方 List<Integer> numbersList = list.stream().map(i -> i * i).collect(Collectors.toList()); // [1, 4, 9, 16, 25, 36, 49, 64, 81] System.out.println(numbersList); List<Integer> evenNumbersList = list.stream().filter(i -> i % 2 == 0).collect(Collectors.toList()); // 筛选出数组中的偶数 [2, 4, 6, 8] System.out.println(evenNumbersList); // 筛选出数组中的奇数并返回元素的平方 List<Integer> numbers = list.stream().filter(i -> i % 2 != 0).map(i -> i * i).collect(Collectors.toList()); System.out.println(numbers);Collector一般用于 stream 操作的结束,用于对结果集做返回值的定义或高级操作。常见操作用于返回特定的集合:Collectors.toList() Collectors.toMap() Collectors.toSet() Collectors.toCollection() Collectors.toConcurrentMap()下面列举常见 demo :List<String> language = List.of("Java", "Python", "Rust", "Go", "C++", "C", "C#", "JavaScript"); // 将数组中元素转化成大写字母并用逗号拼接 String collect1 = language.stream().collect(Collectors.collectingAndThen(Collectors.joining(","), String::toUpperCase)); // JAVA,PYTHON,RUST,GO,C++,C,C#,JAVASCRIPT System.out.println(collect1); // 实现按数组元素进行分组 Map<Integer, List<String>> collect2 = language.stream().collect(Collectors.groupingBy(String::length)); // {1=[C], 2=[Go, C#], 3=[C++], 4=[Java, Rust], 6=[Python], 10=[JavaScript]} System.out.println(collect2); // 转换成字符串长度与字符串的 hash map 有冲突后者覆盖前者 Set<String> collect3 = language.stream().collect(Collectors.toCollection(HashSet::new)); // language.stream().collect(Collectors.toSet()); // [C#, Java, C++, Rust, C, JavaScript, Go, Python] System.out.println(collect3); // 转换成字符串长度与字符串的 hash map 有冲突后者覆盖前者 Map<Integer, String> collect4 = language.stream().collect(Collectors.toMap(String::length, String::new,(existing, replacement) -> existing)); // {1=C, 2=Go, 3=C++, 4=Java, 6=Python, 10=JavaScript} System.out.println(collect4);进阶使用在简单使用中都是比较常见且统一理解的例子。下面看一下一些比较复杂的例子。数据准备Person 类用到了 Lombok 的 Builder、Data 注解。@Builder(toBuilder = true) @Data class Person { private Integer height; private Integer age; private String name; private String city; } Person p1 = new Person.PersonBuilder().name("bob").height(150).city("shanghai").age(15).build(); Person p2 = new Person.PersonBuilder().name("andy").height(160).city("beijing").age(18).build(); Person p3 = new Person.PersonBuilder().name("tom").height(170).city("xian").age(19).build(); Person p4 = new Person.PersonBuilder().name("cat").height(180).city("shanghai").age(25).build(); ArrayList<Person> persons = new ArrayList<>(); persons.add(p1); persons.add(p2); persons.add(p3); persons.add(p4);实例讲解如下代码实现的功能为:将人员数组按照年龄设置额外字段将数组中人员按照城市分组组内结果如有多人取身高最高的一员// 需要关于身高的 Comparator Comparator<Person> byHeight = Comparator.comparing(Person::getHeight); Map<String, Person> collect = persons.stream().peek(item -> { String temp = item.getAge() >= 18 ? "成年" : "未成年"; item.setExtra(temp); }).collect( Collectors.groupingBy( Person::getCity, Collectors.reducing(p1, BinaryOperator.maxBy(byHeight)) ) ); // {xian=Person(height=170, age=19, name=tom, city=xian, extra=成年), shanghai=Person(height=180, age=25, name=cat, city=shanghai, extra=成年), beijing=Person(height=160, age=18, name=andy, city=beijing, extra=成年)} System.out.println(collect);
2021年09月01日
99 阅读
0 评论
0 点赞
2021-08-31
Java中ThreadLocal简单学习使用
文章目录索引ThreadLocal定义该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。以上来源官方API。大概可以总结为两点:ThreadLocal提供get/set方法,可以访问属于当前线程的变量,也就是可以保证每个线程的变量不一样。ThreadLocal使用时通常定义为private static的。从字面意思理解,可能会将ThreadLocal认为是本地线程,其实ThreadLocal并不是线程,而是线程Thread的局部变量。1、如何使用首先,定义一个private static的ThreadLocal对象。private static ThreadLocal<String> threadLocal = new ThreadLocal<>();然后每个线程可以将当前线程需要存放在局部变量中,并且可以从中获取。public void setAndGet(String name) { threadLocal.set(name); String s = threadLocal.get(); }最后在使用完之后,需要将ThreadLocal中的值移除。public void remove() { threadLocal.remove(); }2.原理那么ThreadLocal是如何做到保证每个线程get出来的数据不一样的呢?我们通过源码来看一下。public void set(T value) { Thread t = Thread.currentThread(); // 通过当前线程获取出来一个ThreadLocalMap ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }我们发现在set方法中,会创建一个ThreadLocalMap,然后将要设置的值放在这个Map中,而当前这个ThreadLocal对象作为key;然后再将这个ThreadLocalMap赋值给Thread的threadLocals里。如果去看Thread类的代码会发现,在Thread类中存在两个变量threadLocals和inheritableThreadLocals,它们的类型就是ThreadLocal.ThreadLocalMap。通过下图可以看出Thread,ThreadLocal,ThreadLocalMap三者的关系。这时候我们再看看get()和remove()方法的代码。public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }可以看出来,和我们上面图中的结构一样,get()方法就是从Thread中取出来ThreadLocalMap,然后通过ThreadLocal对象作为Key取出值;remove()方法则是取出ThreadLocalMap将ThreadLocal对应的数据移除。那么ThreadLocalMap到底是什么呢?是java.util.Map接口的子类吗?我们来看源码。static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } private static final int INITIAL_CAPACITY = 16; private Entry[] table; private int size = 0; private int threshold; // Default to 0 // 省略其他代码 }通过源码发现,ThreadLocalMap并没有实现Map接口,也没有集成其他任何的Map类。是定义在ThreadLocal类中的一个静态内部类。而它的结构和HashMap结构极其相似。有一个Entry[]数组存放数据。而这个Entry类是继承自WeakReference类的子类,这一点和HashMap有所不同。ThreadLocalMap和HashMap结构有很多不同,但是还有一点和HashMap不一样,我们来看一下ThreadLocalMap的set方法。private void set(ThreadLocal<?> key, Object value) { Entry[] tab = table; int len = tab.length; // 计算key对应放在tab中的下标 int i = key.threadLocalHashCode & (len-1); //循环遍历tab,首先获取到下标i对应的对象,如果不为空,则执行循环体 // 如果不是相同的threadLocal或者位置失效,则要寻找下一个位置。 for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get(); // 判断与当前ThreadLocal是否是同一个对象,如果是则进行值替换,结束 if (k == key) { e.value = value; return; } // 如果k==null代表threadLocal的key失效了,将失效的key进行替换 if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }代码中循环遍历tab,首先获取到下标i对应的对象,如果不为空,则执行循环体,如果在循环体中的两个条件都不满足,则会执行nextIndex()方法,这个方法的代码如下:private static int nextIndex(int i, int len) { return ((i + 1 < len) ? i + 1 : 0); }这个方法的逻辑就是 开放寻址法 。而HashMap则是通过 拉链法 和 rehash 来做的。3.使用场景通过上面的内容基本可以掌握ThreadLocal的基本用法,那么ThreadLocal主要在什么场景中使用呢。ThreadLocal的作用通过以上了解我们知道主要是用来做线程间数据隔离。那么在什么场景下能用到线程隔离呢?首先想到的就是SimpleDateFormat这个工具类,它不是线程安全的,可以通过ThreadLocal在每个线程中放一份,保证线程安全。还有比如说用户登录的session,或者token数据,只数据当前会话线程,也可以通过ThreadLocal存储。再比如在某些场景下,上下文数据在不同方法之间调用,传递起来非常麻烦,可以通过ThreadLocal存放,只需要在需要用到的地方获取就可以。除了这些场景,在某些框架源码中也会使用到,比如Spring中的事务也主要是通过ThreadLocal和面向切面编程AOP实现的,感兴趣的同学可以查看源码了解。4.避免踩坑内存泄漏ThreadLocalMap中的Entry的Key是一个弱引用,因此如果在使用后不调用remove方法清除掉会导致对应的value内存泄漏。所以在使用完以后一定要记得调用remove方法清除数据。
2021年08月31日
139 阅读
0 评论
0 点赞
2021-08-11
java中xml转移说明
被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”。 此标记用于xml文档中,我们先来看看使用转义符的情况。我们知道,在xml中,”<”、”>”、”&”等字符是不能直接存入的,否则xml语法检查时会报错,如果想在xml中使用这些符号,必须将其转义为实体,如”<”、”>”、”&”,这样才能保存进xml文档。 在使用程序读取的时候,解析器会自动将这些实体转换回”<”、”>”、”&”。举个例子: <age> age < 30 </age> 上面这种写法会报错,应该这样写: <age> age < 30 </age> 值得注意的是: (1)转义序列字符之间不能有空格; (2) 转义序列必须以”;”结束; (3) 单独出现的”&”不会被认为是转义的开始; (4) 区分大小写。 在XML中,需要转义的字符有: (1) & & (2) < < (3) > > (4) " " (5) ' ' 但是严格来说,在XML中只有”<”和”&”是非法的,其它三个都是可以合法存在的,但是,把它们都进行转义是一个好的习惯。 不管怎么样,转义前的字符也好,转义后的字符也好,都会被xml解析器解析,为了方便起见,使用<![CDATA[]]>来包含不被xml解析器解析的内容。但要注意的是: (1) 此部分不能再包含”]]>”; (2) 不允许嵌套使用; (3)”]]>”这部分不能包含空格或者换行。 最后,说说<![CDATA[]]>和xml转移字符的关系,它们两个看起来是不是感觉功能重复了? 是的,它们的功能就是一样的,只是应用场景和需求有些不同: (1)<![CDATA[]]>不能适用所有情况,转义字符可以; (2) 对于短字符串<![CDATA[]]>写起来啰嗦,对于长字符串转义字符写起来可读性差; (3) <![CDATA[]]>表示xml解析器忽略解析,所以更快。
2021年08月11日
337 阅读
0 评论
0 点赞
1
2
3
4
5