spring 源码01 开始阅读
在开始源码阅读之前,一定要使用过这个产品,了解这个产品的功能、特点。
在开始源码阅读之前,需要先明白几个事
是否足够了解
要阅读到什么程序
如何开始、从哪里开始
开始前最好是带着问题去阅读源码,不纠结于小细节。我一般读源码就是碰到问题后,带着问题去看,效果更好,不要想着假大空,把源码当小说一样看。单个问题解决后,再向外延伸,就可以把一些点串起来。最后,需要反复看一些重点部份,消失对源码的陌生感之后就会能看进去。熟悉之后就会一种想要了解更多的感觉就会一直往下看,这个就是自动驱动的动力。
如果看不下去,不要责怪自己懒,人对看不见短期收益的事提不起兴趣这才是正常的一个人,趋利避害是正常的。看不下去,该干嘛干,强迫自己看效果很差。不要骗自己,假装努力是在浪费时间,干IT的都很忙,看不去就看改改bug。
技巧
对说某个功能,在看之前,可以有自己的推测,想像后续的流程是如何执行的。
切一个 read_code 分支用来作注释,写上自己的见解,也方便以后再回到这块代码时能快速理解。
找到真实阅读源码的动力,如:
准备跳槽、面试
想了解原理
解决项目中的问题
装逼
跑测试用例,好的开源软件 ...
spring 源码阅读环境
要进行源码阅读之前,强调需要先对一个产品有熟悉的使用,就好像你想要造车,要先会开车,再去学习如何造车,否则一切都是停在理轮上,完全不了解这个车是如何运行的,没有概念。推荐对需要阅读的源码先保存在自己仓库中,并创建一个源码分支,可以在阅读分析的过程中对重要点进行注释帮助加深理解。
fork源码Spring 官方github源码仓库
https://github.com/spring-projects/spring-framework
构建源码阅读环境将代码 clone 到本地,克隆完成后,IDEA自动打开项目。
报错处理,首次打开会报个错,别慌这是因为IDEA缺少必要插件,点右侧 gradle 的构建按钮构建一次。
首次构建需要下载的包比较多,
直接使用 git clone 方式直接使用命令行git clone 项目的话,拉完代码后,IDEA 通过导入的方式导入项目。
file--->new--->Project from Exisitings Sources
后续步骤相同。
gradle 问题spring 是基于gradle进行构建的,如果没有安装gradle也没 ...
spring cloud eureka 注册服务显示IP端口号
Spring cloud 显示 INSTANCE-ID 如果以IP + 端口号的形式显示,会更清析的定位每个服务所在的机器节点的状态。
依赖的 pom12345<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-commons</artifactId> <version>2.1.0.RELEASE</version></dependency>
yml 相关配置1234567eureka: client: service-url: defaultZone: http://10.168.16.101:8761/eureka/ instance: instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${serve ...
spring cloud 四种服务下线方式
这里指已经在 Eureka 注册中心注册的服务,如果需要停用,有四种方式进行停用。
1.直接关闭最粗暴。写这个是因为,直接关闭,如果 Eureka 开了保护模式,会导至服务已关闭,但是未下线,还是会重试调用。如果不需强稳定性的话可以这么干。
2.客户端主动通知注册中心下线安全。Eureka注册中心在收到某个客户端下线后不会马上通知所有的注册的客户端,而是等到客户端进行心跳的时候(心跳(续约)频率,默认30秒 )再将下的数据返回。通过这种方式下线的话,可以在某个服务下线后防止其他服务调用此服务失败。
白话就是,服务状态下线了,但是不通知其他服务。等到续约时间到了,再通知所有注册服务。
猜测,服务下线后,在没有心跳前,其他服务还是可以进行调用。等到心跳后,通知所有服务已下线,其他服务认为已下线,就不会再调该下线服务。
12345678 @Autowired private DiscoveryClient client; @ResponseBody @GetMapping("/eurekaUnRegister") public String shut ...
springboot 发送邮件
最近重写一个邮件服务来给告警业服务用,做成一个内置的应用。直接使用 spring 的 javamail 来实现。公司使用腾讯企业邮箱。这个例子正常使用,可以直接套上使用。
邮件配置以下配置方式二选一
代码方式
yml方式
代码方式1234567891011121314151617181920212223242526272829303132333435363738394041424344454647package com.liukai.springmail.send;import org.springframework.beans.factory.annotation.Configurable;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.boot.autocon ...
java 解决父构造器中拿到对象
这两天被问到一个有意思的问题,就是如果在构造器中拿到匿名对象。这个问题有意思在,直觉上是可以通过外部放一个成员变量去接,然后后续就可以使用了,但实际不行。
问题复现下面这个是构造器,当通过 supper 去调用父类构造器。由于问题出现在Spring项目当中,所以我复现的例子也基于Spring重新搭了一个项目来复现这个过程,代码放github上。
复现demo:
12345678910111213package com.test;import org.springframework.beans.factory.annotation.Autowired;public class TransactionCache extends RevokingDB { @Autowired public TransactionCache(String dbName) { // 其他代码不能在 supper 之前,但是又要拿到 TxCacheDB,不能再new一次,否则会初始化两次TxCacheDB。 super(new TxCacheDB(dbName)); // ...
静态资源配置的问题
spring boot 的项目是将静态资源打包到.jar 的文件包中, 项目中有碰到需要使用外部静态资源的情况,使用外部资源的一直老出问题,查了google 后发现是指定的方式不对。
静态资源配置将 resource/static 进行映射,springboot 默认优先级:
/META-INF/resources//resources//static//public/
spring 属性合配 resources 配置1.本项目包含路径:
12345spring:mvc: static-path-pattern: /lateresources: static-locations: classpath:/templates/dist/
这两天遇到的坑
2.指定项目外的磁盘路径如果要映射本地磁盘路径,可以使用,注意必须得有 file:, 注意必须得有file:,注意必须得有file: 否则 404, 重要事情说三遍。
12345spring:mvc: static-path-pattern: /lateresources: static-locations: fil ...
springboot 注解实现日志切面
项目中很多时候需要去打印方法入参和出参的日志,有助于排查错误。注解需要操作简单。常用的方式之一就是使用切面来切日志。
步骤:
定义自定义注解
编写自定义注解的切面方法
使用注解在需要输出日志的方法上
1.自定义注解1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253/** * * controller 注解切面 * @author liukai * @data 2018/8/7 15:26. */@Target({ElementType.PARAMETER, ElementType.METHOD})//目标是方法@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取@Documented//文档生成时,该注解将被包含在javadoc中,可去掉@Inheritedpublic @interface ControllerLog { /** ...
什么是上下文context
上下文(背景/语境) context是当前运行程序的环境。网上各种不可说,模糊不清,但是一个概念的提出肯定有最初的含义。
总结上下文可以理解成:
上下文指由代码已运行的程序环境,不是指代码。
一组状态,这个好理解,取 spring cloud 的官方文档的例子:
一个Spring Cloud应用程序通过创建一个"引导"上下文来进行操作,这个上下文是主应用程序的父上下文。引导上下文使用与主应用程序上下文不同的外部配置约定,因此使用bootstrap.yml application.yml(或.properties)代替引导和主上下文的外部配置。这里所谓的 引导上下文 就是一组状态,实际就是一个保存配置的大对象,换个角度理就是环境。
环境背景每一段程序都有很多外部变量。只有像Add这种简单的函数才是没有外部变量的。一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行。你为了使他们运行,就要给所有的外部变量一个一个写一些值进去。这些值的集合就叫上下文。
摘自知乎
和其他传入对象参数没什么区别。但是通常使用Context来描述有几个特点:被传入Context的 ...
spring boot 使用maven打jar包配置
使用 ide 进行开发时,直接在ide上启动即可,如果要放到服务器上进行使用,就必须打成jar包,这里使用 maven 的打包插件进行打包。注意 <mainClass>com.devops.WebApplication</mainClass> 这行要改成你的启动类。
1234567891011121314151617181920212223242526272829303132<build> <finalName>devops-web</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> ...