1. 看了一些讲解spring的书,但是感觉还是不够深,所有想自己看看spring的源码,看源码的时候可以写一些代码跑起来,本地调试一下应该会更好理解
  2. 有一些社区是做了官方文档的中文翻译,质量很高,大概是比一些出版的书籍要更加权威,docs4dev社区-spring-5.1.3中文文档
  3. 本次选择的spring版本是5.1.3,主要是中文文档也是最高这个版本,方便对的上,源码下载地址

    环境要求

    gradle

  4. spring是使用gradle-4.10.2版本构建的,idea会自动安装并引用,如果有问题再手动
  5. 版本要求可见源码文件:gradle/wrapper/gradle-wrapper.properties
  6. 下载后先配置环境变量
  7. 然后在文件 init.d 目录下新增一个文件 init.gradle 这个是下载包的仓库配置
  8. 配置内容可以复制下面的内容:
    allprojects{
     repositories {
      def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/nexus/content/groups/public'
      def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/nexus/content/repositories/jcenter'
      def GRADLE_LOCAL_RELEASE_URL = 'https://repo.gradle.org/gradle/libs-releases-local'
      def ALIYUN_SPRING_RELEASE_URL = 'https://maven.aliyun.com/repository/spring-plugin'
            
      all { ArtifactRepository repo ->
          if(repo instanceof MavenArtifactRepository){
              def url = repo.url.toString()
              if (url.startsWith('https://repo1.maven.org/maven2')) {
                  project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
                  remove repo
              }
              if (url.startsWith('https://jcenter.bintray.com/')) {
                  project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
                  remove repos
              }
              if (url.startsWith('https://repo.spring.io/plugins-release')) {
                  project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_SPRING_RELEASE_URL."
                  remove repo
              }
          }
      }
      maven {
          url ALIYUN_REPOSITORY_URL     
      }
            
      maven {            
          url ALIYUN_JCENTER_URL          
      }
      maven {            
          url ALIYUN_SPRING_RELEASE_URL
      }
      maven {
          url GRADLE_LOCAL_RELEASE_URL
      }
     }
    }
    

    JDK

  9. spring5.1.3 使用了一些语法低版本JDK不支持(9以下都不行),所以JDK直接选择java17,当你使用JDK17的时候,编译时报如下错误的时候,可以选择将JDK切换回8,因为我当时是mac上直接使用java17成功了,windows上使用java8成功,也许java11刚好合适:

    java.util.Map java.lang.ProcessEnvironment.theCaseInsensitiveEnvironment accessible: module java.base does not “opens java.lang” to unnamed module @d041cf

  10. 下载后配置好环境变量

    开发工具 IDEA 配置

  11. 我使用的是2022版本,将spring项目导入,先什么也不做,等它自动加载完,idea提示安装什么东西就允许即可,加载完毕后再进行下面的设置
  12. 文件->设置->构建 执行 部署->编译器->java编译器>选择编译版本 17
  13. 文件->设置->构建 执行 部署->构建工具->Gradle 配置好前面下载的gradle程序地址,同时gradle jvm 选择17
  14. 文件->项目结构->平台设置->SDK 添加自己下载的jdk 17
  15. 文件->项目设置->项目 设置java 17
  16. 文件->项目设置->模块 将所有模块设置成 java 17
  17. 文件->设置->插件->Marketplace 中搜索 Translation 安装这个插件后重启,然后再进入 文件->设置->工具->翻译 在右侧面板最下面,其它->翻译文档勾住,设置上方的翻译引擎,如果没有VPN,可以使用国内的翻译引擎,注册一个开发者id配置上去即可(国内的应该会收费,不推荐),然后看源码的时候,将鼠标放到类(可按Ctrl+Q快捷键)或者方法上就会触发翻译
  18. 文件->设置->外观与行为->系统设置->HTTP 代理 如果使用的翻译是谷歌翻译,需要在这里设置VPN代理(使用的VPN软件大多数都有开放端口支持http,socket代理等功能)否则谷歌翻译可能会访问不到网络,有些vpn软件也许不需要再idea进行设置因为它有可能就是全局代理,只需要保证网络较好即可。
  19. 如果是英文版的idea找好对应位置就行

    在spring源码工程中创建自己的学习项目包

  20. 选择项目根包,右击->新建->新模块 选择gradle构建模块包,包名可以叫做 spring-study
  21. 找到根目录下的 build.gradle 文件,打开后 搜索 -Werror ,然后把它删除掉,这个地方会影响编译,我不删除这个的时候,自己创建的包使用spring注解的时候,无法编译通过,会一直报错误 因为配置了 -Werror
  22. 打开spring-study 包下的 build.gradle 文件, 在 dependencies 层级下添加如下配置,如果不满足依赖,比如想试试web,则可以多加上implementation(project(“:spring-web”))其它子模块也是一样的添加方式
     implementation(project(":spring-core"))
     implementation(project(":spring-beans"))
     implementation(project(":spring-context"))
    
     compileOnly 'org.projectlombok:lombok:1.18.24'
     annotationProcessor 'org.projectlombok:lombok:1.18.24'
    
     testCompileOnly 'org.projectlombok:lombok:1.18.24'
     testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'
    
     testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
     testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
    

    开始编写代码启动spring

  23. 因为我只想启动轻量级spring,不想启动web服务,所以选择AnnotationConfigApplicationContext 来启动
  24. 启动时的扫包路径以及一些注解,就跟平时使用spring的时候一样,创建一些servic类,带上注解@Service即可
  25. 这样看spring源码的环境就搭建好了,使用spring框架的时候,都是调用的本地的代码,也方便调试
  26. main函数如下:
    @Configuration
    @ComponentScan({"org.springframework.main1"})
    public class Main1 {
     public static void main(String[] args) {
         ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(Main1.class);
         UserService us = applicationContext.getBean(UserService.class);
         System.out.println(us.getUserInfo().toString());
     }
    }
    
  27. UserService 类如下:
    @Component
    public class UserService {
    
     public UserDo getUserInfo(){
         UserDo ud = new UserDo();
         ud.setName("谭峻");
         ud.setAge(28);
         return ud;
     }
    }
    
  28. UserDo 类如下:
    @Setter
    @Getter
    @ToString
    public class UserDo {
     private String name;
     private int age;
    }