首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

使用Java类加载SpringBoot、SpringCloud配置文件

版权声明:本文为博主原创文章,未经博主允许不得转载。博客源地址为zhixiang.org.cn https://blog.csdn.net/myFirstCN/article/details/81750872 我们都知道平常在使用SpringBoot和SpringCloud的时候,如果需要加载一两个配置文件的话我们通常使用@Value("${属性名称}")注解去加载。但是如果配置文件属性特别多的时候使用这种方式就显得特别的不友好了。 比如说,我们要加载下方这个名为application.yml的配置文件。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 kafka: brokerAddress: 110.35.113.62:9092,123.27.143.72:9095,180.17.133.52:9096 smsTopic: testTopic smsCosumeGroup: testTopicGroup timerTaskTopic: timerTopic timerTaskGroup: timerGroup jvmNumbers: 3 security: authentication: jwt: secret: 0550224055e1848081dba46d8ad325f503fa141b tokenValidityInSeconds: 86400 此时我们有两种方式来简化这个加载方式 1 这种方式呢,是同过层层嵌套的方式一层一层的按照配置文件属性的方式来进行注入的。大家只要把这个类跟上方提供的配置文件进行对比就会明白它的方式了。(注意,下方的所有属性因为篇幅问题没有增加get、set方法,实际使用过程中请自行添加) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) public class ApplicationProperties1 { private final Security security = new Security(); private final Kafka kafka = new Kafka(); public static class Kafka { private String brokerAddress; private String smsTopic; private String smsCosumeGroup; private String timerTaskTopic; private String timerTaskGroup; private String jvmNumbers; } public static class Security { private final Authentication authentication = new Authentication(); public static class Authentication { private final Jwt jwt = new Jwt(); public static class Jwt { private String secret; private long tokenValidityInSeconds; } } } } 2 这种方式就是以指定的配置前缀为依据去取配置(同上没有写get、set方法) 例如:kafka的配置可以这样来 1 2 3 4 5 6 7 8 9 10 11 12 @Configuration @ConfigurationProperties(prefix = "kafka",ignoreUnknownFields = false) @PropertySource(value = { "classpath:application.yml" },ignoreResourceNotFound=false) public class ApplicationProperties { private String brokerAddress; private String smsTopic; private String smsCosumeGroup; private String timerTaskTopic; private String timerTaskGroup; private String jvmNumbers; } 而Security的配置这样来 1 2 3 4 5 6 7 8 9 @Configuration @ConfigurationProperties(prefix = "security.authentication.jwt",ignoreUnknownFields = false) @PropertySource(value = { "classpath:application.yml" },ignoreResourceNotFound=false) public class ApplicationProperties { private String secret; private long tokenValidityInSeconds; } 补充 大家可能会注意到我上方的几个类中都没有写get和set方法,因为那个东西其实所占的篇幅实在是太长了。那么,有什么办法可以补救么,其实是有办法的,一个注解就可以全搞定哟。 什么?你不信,不信来看看呀:IDEA中使用lombok插件 结语 怎么样,学会这个以后Leader还会担心你的代码臃肿么。 本文出自http://zhixiang.org.cn,转载请保留。

优秀的个人博客,低调大师

Java记忆篇 - 关键字与保留字

共“53”个关键字(含2个保留字) 保留字 1).const有道释义:n.常量,常数 用于修改字段或局部变量的声明。它指定字段或局部变量的值是常数,不能被修改 2).goto有道释义:vi.转到 指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。 访问修饰符的关键字(共3个) 定义类、接口、抽象类和实现接口、继承类的关键字、实例化对象(共6个) 包的关键字(共2个) 数据类型的关键字(共12个) 条件循环(流程控制)(共12个) 修饰方法、类、属性和变量(共9个) volatile 1.当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制刷新到主内存中去; 2.这个写会操作会导致其他线程中的缓存无效。 上面的例子只需将status声明为volatile,即可保证在线程A将其修改为true时,线程B可以立刻得知 volatile boolean status = false; 错误处理(共5个) 其他 publicenumColor{RED,BLUE,GREEN,BLACK;}

优秀的个人博客,低调大师

Java 数组 之 一维数组 冒泡排序算法

http://www.verejava.com/?id=16992682424030 /** 用冒泡算法:将成绩arrays 从小到大排序输出 思路: 第一趟排序 1. 将数组中n个元素从第一个元素开始 一一跟后面的元素比较 2. 如果前面的数据比后面的数据大, 两个交换位置直到一次循环完成,那么数组中最大的数据将会排在数组的最后一个位置。 第 i 趟排序 3. 依次类推, 将剩下未排序的n-i个元素再类似 1,2过程一遍,这样直到循环 n次结束后,数组中的元素就是从小到大排好序了. 注意: 只需要经过 n-1趟排序 */ public class BubbleSort { public static void sort(int[] arrays) { //第一个循环控制n-1趟排序 for (int i = 0; i < arrays.length - 1; i++) { //第二个循环控制每次要比较的元素个数n-1 for (int j = 0; j < arrays.length - i - 1; j++) { if (arrays[j] > arrays[j + 1]) { int flag = arrays[j]; arrays[j] = arrays[j + 1]; arrays[j + 1] = flag; } } } } public static void main(String[] args) { //一维数组的定义和初始化 int[] scores = { 90, 70, 50, 80, 60, 85 }; sort(scores); //输出排序后的 scores for (int i = 0; i < scores.length; i++) { System.out.print(scores[i] + ","); } } } http://www.verejava.com/?id=16992682424030

优秀的个人博客,低调大师

java -----------------LeetCode——电话号码的字母组合

回溯算法是不是很是陌生啊,我敢开始也是一脸你蒙蔽,后来我终于忍不住了,就去查查什么是回溯,原来是这个情况,回溯和递归有点类似,但是又不是递归,比如我现在计算数据从0开始到2,当到达状态值2我就回溯,我从1开始回溯,我在回到0,就是for循环我不按套路从小到打,去输出了,我采用回溯, public class Main { public static void main(String[] args) { List<String> stringList = begin("23"); System.out.println(stringList.toString()); } // 定义每个数字对应的字符 static String[] a = new String[] {"","","abc","def", "ghi","jkl","mno","pqrs","tuv","wxyz"}; // 这个是输出的字符串 static StringBuffer sb = new StringBuffer(); private static List<String> begin(String str) { if (str.length() == 0) { return null; } List<String> result = new ArrayList<>(15); zihe(str,0,result); return result; } private static void zihe(String str, int n, List<String> result) { if (n == str.length()) { result.add(sb.toString()); return; } for (int i = 0; i < a[str.charAt(n)-'0'].length(); i++) { sb.append(a[str.charAt(n)-'0'].charAt(i)); zihe(str, n + 1, result); sb.deleteCharAt(sb.length() - 1); } } }

优秀的个人博客,低调大师

JAVA以后是怎么找工作的呢?

最低什么程度就可以出去碰碰运气? 我这里并不是教大家投机取巧,而是为不了解求职的小白朋友提供一个参考。理论上当然是基础越牢固越好,你最好把科班的“四大课”都啃了。 就我自己做外包的经验,基本上培训视频中ssm框架往后教的就用不太到了,什么redis,ActiveMQ负载均衡等等,都用不太到(但我不敢打包票)。而且你一个零基础的,学了能咋滴?工作一两年的人都没怎么搞透的技术,你还能用它写出花?最多学会几个单词罢了。总之,如果你没有朋友内推,没有过人天赋,我默认你和我一样,学得再好几个月刚出来也就外包水平。那么既然做外包,视频中电商项目啦、高并发这些都和你没什么关系了。甚至什么maven也和你没什么关系。什么?你说导包太繁琐、自己不会独立搭建ssm框架?别逗了老铁,给你几千块,你还真当自己是架构师啊....外包工作基本就是ssm一套,前端搞个layui或者easyui这种第三方模块化框架凑合一下,而这些环境都是项目经理给你搭好的,你就是增删改查而已。另外,你要知道,外包很少有什么前端工程师、后端工程师之分的,给你一把键盘,你就是从前台页面撸到后台数据库的“全绽”工程师。也就是什么都会一点,但是代码都是“破绽”的码农。所以有心思搞什么高并发,还是学好怎么切图做页面吧。 但我也要对我说的话负责,万一你们心直,信了我的话,学完ssm就出去骗钱,然后被社会主义无情扇耳光,我也是很心痛的。给个重点吧: 1.JavaSE基础: 一定要好好学,很多人都不明白基础的重要性。上来就什么ssm,springBoot,redis。比谁认识的单词多吗?面向对象、字符串处理、集合、IO一定要重点学!2.JavaWeb前端:不要老一副吊样,觉得自己出去就是后端工程师,不学什么HTML, CSS, JavaScript。老铁,不存在的。进了外包公司你万一发现后台逻辑简单的一逼,就几个接口,反而前端页面切个图都要一天,难道你还好意思暗搓搓问老板:怎么我们公司没有前端的吗?所以前端一定要重视。div+css布局一定要麻溜的,js的dom操作必须给力。jQuery/bootstrap你必须会吧!3.JavaWeb服务器端:Tomcat目录结构必须了如指掌吧。让你手动部署个webapp总要会吧。哪里配置虚拟主机,哪里改端口号,web-info文件夹下的内容外部无法访问这些都要懂一点吧?这些皮毛都不懂,怎么好意思说自己搞服务器端?jsp和servlet什么关系,servlet最常见的三种创建方式,Javaweb四大域对象,jsp九大内置对象都要知道吧?el表达式必须熟悉吧?mysql增删改查sql语句要会写吧,多表关联、左外右外不能怂吧?jdbc是干嘛的,sql注入是啥,如何用jdbc实现事务等等都要知道吧?4.框架预备知识:xml读写操作要知道,反射、内省、泛型不要求精通,但怎么用总要心里有点那个什么数吧。不然你框架学起来就是懵逼的。5.ssh、ssm框架:不要求你精通底层原理,但是山寨版的原理总要略知一二吧。如何山寨实现IoC容器,如何对dao进行抽取,如何借助反射实现同一个servlet处理多个请求,这些最好都要了解吧。在理解山寨版框架的基础上,把配置多配几遍,做到心里有数。明白每个配置大致起到什么作用。另外,我一向觉得,学习框架必须带着下面的疑问:这个框架没有出现之前,我们的前辈们如何解决的?它的出现解决了哪些痛点?又有什么缺点没有?都是需要去琢磨的。最后,还是忍不住说一下,很多小白老是觉得框架是学习路上的终极boss。too young, too simple. Sometimes naive! 框架如果不细究底层(我承认底层很复杂),其实完全可以看做很大很大的工具类。只不过以前我们写代码调工具类,现在我们写点代码让框架调...工具类就像钥匙,是工具,我们用它开门。框架就像房子,我们的代码是窗户,窗户是嵌在房子了的。反正,框架不是大boss,你的项目经验和编码能力才是拦路虎! 2.学到什么程度比较保险? 那这个就没有上限了。你面试上去就说:我,20年开发经验,6岁开始开发。对方就应该准备递烟了。但是很显然,你没有经验。没有经验,那么大公司就会要求你基础要扎实。你越往后学,就会越发现自己和科班出身的朋友的差距。就好比你开车,能到目的地不被违章拍照就好了。而人家开车,考虑的是乘客的舒适性、耗油、轮胎磨损等等。这个时候,是不是老司机就高下立判了。你没有底层知识的支撑,难免浮沙筑高台。要么后期心有余力不足,要么垮了。所以,我建议啊,培训班视频ssm后面的内容可以看,也鼓励多学一点。但是能掌握多少,到时你自己就知道了。压根就是天书,听完就忘。你只是学到几个高级单词,还心里美滋滋。所以还在校,不急着找工作的朋友,建议数据结构,操作系统有时间都学学。万一你出来找不到工作,还可以曲线救国,先去考个计算机的研究生,然后出来报复社会呢?考研基本上数据结构,操作系统必考啊... 最后呢,建议大家不要执着。现在转行工作真的不好找。360行,哪条不是路呢?更不要贸然裸辞,今天看IT人傻钱多,第二天就裸辞。脱衣服都没见你这么快的。大可以先自学试试,万一你发现你一学编程就脱发,女朋友就闹着分手呢? 最后,给个路线吧,我8个月学出来差点找不到工作,很是心酸。但是有了我这个路线相信你只要6个月 此文章为隋七哥原创,特此声明!”

优秀的个人博客,低调大师

Java并发编程笔记之ThreadLocal内存泄漏探究

使用 ThreadLocal 不当可能会导致内存泄露,是什么原因导致的内存泄漏呢? 我们首先看一个例子,代码如下: /** * Created by cong on 2018/7/14. */ public class ThreadLocalOutOfMemoryTest { static class LocalVariable { private Long[] a = new Long[1024*1024]; } // (1) final static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(6,6,1,TimeUnit.MINUTES, new LinkedBlockingQueue<>()); // (2) final static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<LocalVariable>(); public static void main(String[] args) throws InterruptedException { // (3) for (int i = 0; i < 50; ++i) { poolExecutor.execute(new Runnable() { public void run() { // (4) localVariable.set(new LocalVariable()); // (5) System.out.println("use local varaible"); // localVariable.remove(); } }); Thread.sleep(1000); } // (6) System.out.println("pool execute over"); } } 代码(1)创建了一个核心线程数和最大线程数为 6 的线程池,这个保证了线程池里面随时都有 6 个线程在运行。 代码(2)创建了一个 ThreadLocal 的变量,泛型参数为 LocalVariable,LocalVariable 内部是一个 Long 数组。 代码(3)向线程池里面放入 50 个任务。 代码(4)设置当前线程的 localVariable 变量,也就是把 new 的 LocalVariable 变量放入当前线程的 threadLocals 变量。 由于没有调用线程池的 shutdown 或者 shutdownNow 方法所以线程池里面的用户线程不会退出,进而 JVM 进程也不会退出。 运行后,我们立即打开jconsole监控堆内存变化,如下图: 接着,让我们打开 localVariable.remove() 注释,然后在运行,观察堆内存变化如下: 从第一次运行结果可知,当主线程处于休眠时候进程占用了大概 75M 内存,打开 localVariable.remove() 注释后第二次运行则占用了大概 25M 内存,可知没有写 localVariable.remove()时候内存发生了泄露,下面分析下泄露的原因,如下: 第一次运行的代码,在设置线程的 localVariable 变量后没有调用localVariable.remove()方法,导致线程池里面的 5 个线程的 threadLocals 变量里面的new LocalVariable()实例没有被释放,虽然线程池里面的任务执行完毕了,但是线程池里面的 5 个线程会一直存在直到 JVM 退出。这里需要注意的是由于 localVariable 被声明了 static,虽然线程的 ThreadLocalMap 里面是对 localVariable 的弱引用,localVariable 也不会被回收。运行结果二的代码由于线程在设置 localVariable 变量后即使调用了localVariable.remove()方法进行了清理,所以不会存在内存泄露。 接下来我们要想清楚的知道内存泄漏的根本原因,那么我们就要进入源码去看了。 我们知道ThreadLocal 只是一个工具类,具体存放变量的是在线程的 threadLocals 变量里面,threadLocals 是一个 ThreadLocalMap 类型的,我们首先一览ThreadLocalMap的类图结构,类图结构如下图: 如上图 ThreadLocalMap 内部是一个 Entry 数组, Entry 继承自 WeakReference,Entry 内部的 value 用来存放通过 ThreadLocal 的 set 方法传递的值,那么 ThreadLocal 对象本身存放到哪里了吗? 下面看看 Entry 的构造函数,如下所示: Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } 接着我们再接着看Entry的父类WeakReference的构造函数super(k),如下所示: public WeakReference(T referent) { super(referent); } 接着我们再看WeakReference的父类Reference的构造函数super(referent),如下所示: Reference(T referent) { this(referent, null); } 接着我们再看WeakReference的父类Reference的另外一个构造函数this(referent , null),如下所示: Reference(T referent, ReferenceQueue<? super T> queue) { this.referent = referent; this.queue = (queue == null) ? ReferenceQueue.NULL : queue; } 可知 k 被传递到了 WeakReference 的构造函数里面,也就是说 ThreadLocalMap 里面的 key 为 ThreadLocal 对象的弱引用,具体是 referent 变量引用了 ThreadLocal 对象,value 为具体调用 ThreadLocal 的 set 方法传递的值。 当一个线程调用 ThreadLocal 的 set 方法设置变量时候,当前线程的 ThreadLocalMap 里面就会存放一个记录,这个记录的 key 为 ThreadLocal 的引用,value 则为设置的值。 但是考虑如果这个 ThreadLocal 变量没有了其他强依赖,而当前线程还存在的情况下,由于线程的 ThreadLocalMap 里面的 key 是弱依赖,则当前线程的 ThreadLocalMap 里面的 ThreadLocal 变量的弱引用会被在 gc 的时候回收,但是对应 value 还是会造成内存泄露,这时候 ThreadLocalMap 里面就会存在 key 为 null 但是 value 不为 null 的 entry 项。 其实在 ThreadLocal 的 set 和 get 和 remove 方法里面有一些时机是会对这些 key 为 null 的 entry 进行清理的,但是这些清理不是必须发生的,下面简单讲解ThreadLocalMap 的 remove 方法的清理过程,remove 的源码,如下所示: private void remove(ThreadLocal<?> key) { //(1)计算当前ThreadLocal变量所在table数组位置,尝试使用快速定位方法 Entry[] tab = table; int len = tab.length; int i = key.threadLocalHashCode & (len-1); //(2)这里使用循环是防止快速定位失效后,变量table数组 for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { //(3)找到 if (e.get() == key) { //(4)找到则调用WeakReference的clear方法清除对ThreadLocal的弱引用 e.clear(); //(5)清理key为null的元素 expungeStaleEntry(i); return; } } } private int expungeStaleEntry(int staleSlot) { Entry[] tab = table; int len = tab.length; //(6)去掉去value的引用 tab[staleSlot].value = null; tab[staleSlot] = null; size--; Entry e; int i; for (i = nextIndex(staleSlot, len); (e = tab[i]) != null; i = nextIndex(i, len)) { ThreadLocal<?> k = e.get(); //(7)如果key为null,则去掉对value的引用。 if (k == null) { e.value = null; tab[i] = null; size--; } else { int h = k.threadLocalHashCode & (len - 1); if (h != i) { tab[i] = null; while (tab[h] != null) h = nextIndex(h, len); tab[h] = e; } } } return i; } 代码(4)调用了 Entry 的 clear 方法,实际调用的是父类 WeakReference 的 clear 方法,作用是去掉对 ThreadLocal 的弱引用。 代码(6)是去掉对 value 的引用,到这里当前线程里面的当前 ThreadLocal 对象的信息被清理完毕了。 代码(7)从当前元素的下标开始看 table 数组里面的其他元素是否有 key 为 null 的,有则清理。循环退出的条件是遇到 table 里面有 null 的元素。所以这里知道 null 元素后面的 Entry 里面 key 为 null 的元素不会被清理。 总结: 1.ThreadLocalMap 内部 Entry 中 key 使用的是对 ThreadLocal 对象的弱引用,这为避免内存泄露是一个进步,因为如果是强引用,那么即使其他地方没有对 ThreadLocal 对象的引用,ThreadLocalMap 中的 ThreadLocal 对象还是不会被回收,而如果是弱引用则这时候 ThreadLocal 引用是会被回收掉的。 2.但是对于的 value 还是不能被回收,这时候 ThreadLocalMap 里面就会存在 key 为 null 但是 value 不为 null 的 entry 项,虽然 ThreadLocalMap 提供了 set,get,remove 方法在一些时机下会对这些 Entry 项进行清理,但是这是不及时的,也不是每次都会执行的,所以一些情况下还是会发生内存泄露,所以在使用完毕后即使调用 remove 方法才是解决内存泄露的最好办法。 3.线程池里面设置了 ThreadLocal 变量一定要记得及时清理,因为线程池里面的核心线程是一直存在的,如果不清理,那么线程池的核心线程的 threadLocals 变量一直会持有 ThreadLocal 变量。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册