项目目录结构
- config:代码检查配置文件夹
- gradle:gradle-wrapper文件夹
- src/main/java/run/halo/:源代码文件夹
- app:应用程序文件夹
- annotation:自定义注解
- aspect:自定义注解的切面
- cache:缓存优化
- config:自定义配置类
- controller:控制层(连接前端和后端)
- core:包含模板引擎和xxx
- event:事务管理
- exception:异常管理
- factory:
- filter:过滤器
- handler:数据迁移、文件、主题处理器
- listener:监听器
- mail:邮件管理
- model:
- repository:数据库层(CRUD操作)
- security:安全层
- service:业务层(用于处理控制层分发的请求)
- task:
- theme:博客主题相关
- utils:工具类
- resource:资源文件夹
- app:应用程序文件夹
gradle
gradle文件夹
Gradle-Wrapper是什么?
Halo官方推荐使用Gradle-Wrapper,这是个什么东西呢?
Gradle-Wrapper译为Gradle包装器,由于每个人在开发时都会在电脑安装Gradle,这就会存在Gradle环境与版本的差异。为了解决这个问题,Gradle提供了一个解决方案,那就是Gradle Wrapper,它是一个脚本,可以在计算机没有安装Gradle的情况下运行Gradle构建,并且能够指定Gradle的版本,开发人员可以快速启动并运行Gradle项目,而不必手动安装,这样就标准化了项目,从而提高了开发效率。
项目根目录下的Gradle文件如下:
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
每个文件的含义如下:
- gradle-wrapper.jar :包含Gradle运行时的逻辑代码。
- gradle-wrapper.properties :负责配置包装器运行时行为的属性文件,用来配置使用哪个版本的Gradle等属性。
- gradlew:Linux平台下,用于执行Gralde命令的包装器脚本。
- gradlew.bat:Windows平台下,用于执行Gralde命令的包装器脚本。
配置Gradle Wrapper
gradle-wrapper.properties用来配置使用哪个版本的Gradle等属性,Halo中使用的gradle-wrapper.properties如下所示:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
各个字段的含义如下:
- distributionBase:Gradle解包后存储的主目录。
- distributionPath:distributionBase指定目录的子目录。distributionBase+distributionPath就是Gradle解包后的存放位置。
- distributionUrl:Gradle发行版压缩包的下载地址。
- zipStoreBase:Gradle压缩包存储主目录。
- zipStorePath:zipStoreBase指定目录的子目录。zipStoreBase+zipStorePath就是Gradle压缩包的存放位置。
build.gradle
build.gradle类似于maven中的pom.xml都是用来对项目进行最基本的管理。
下面我们对build.gradle中每一个字段进行解释:
-
//plugins{}:这种方式引入的插件来自Gradle官方插件库 plugins { id "org.springframework.boot" version "2.5.1" id "io.spring.dependency-management" version "1.0.11.RELEASE" id "checkstyle" id "java" }
-
//使用依赖的项目所在的组 group = "run.halo.app" //项目描述 description = "Halo, An excellent open source blog publishing application." //指定编译.java文件的jdk版本 sourceCompatibility = JavaVersion.VERSION_11
-
//配置代码质量检查 checkstyle { toolVersion = "8.39" showViolations = false ignoreFailures = false }
-
//这里类似maven的仓库 repositories { //使用本地仓库http://central.maven.org/作为maven仓库的路径 mavenLocal() //使用中央仓库 mavenCentral() //使用远程仓库URL maven { url 'https://repo.spring.io/milestone' } //jcenter是一个由 bintray.com维护的Maven仓库 jcenter() }
-
/** * Gradle将对依赖进行分组,比如编译Java时使用的是这组依赖,运行Java时又可以使用另一组依赖。 * 每一组依赖称为一个Configuration,在声明依赖时,我们实际上是在设置不同的Configuration。 */ configurations { //implementation和api是取代之前的compile的,其中api和compile是一样的效果,implementation有所不同,通过implementation依赖的库只能自己库本身访问,举个例子,A依赖B,B依赖C,如果B依赖C是使用的implementation依赖,那么在A中是访问不到C中的方法的,如果需要访问,请使用api依赖 implementation { exclude module: "spring-boot-starter-tomcat" exclude module: "slf4j-log4j12" exclude module: 'junit' } //compile only和provided效果是一样的,只在编译的时候有效, 不参与打包 compileOnly { //依赖于annotationProcessor extendsFrom annotationProcessor } }
-
//打包 bootJar { //指定依赖包的名称和版本 manifest { attributes "Implementation-Title": "Halo Application", "Implementation-Version": archiveVersion } }
-
//创建docker镜像 bootBuildImage.doFirst { // check data assert System.getenv("DOCKER_USERNAME") != null assert System.getenv("DOCKER_TOKEN") != null } bootBuildImage { // prepare data def tagLatest = Boolean.valueOf(System.getenv("TAG_LATEST")) def dockerImageName = System.getenv("DOCKER_IMAGE_NAME") def dockerUsername = System.getenv("DOCKER_USERNAME") def dockerToken = System.getenv("DOCKER_TOKEN") if (dockerImageName == null) { dockerImageName = "${dockerUsername}/halo" } if (!tagLatest) { dockerImageName = "${dockerImageName}:${project.version}" } // config plugin imageName = "${dockerImageName}" docker { publishRegistry { username = "${dockerUsername}" password = "${dockerToken}" email = "hi@halo.run" } } }
-
//本质上是一个map,一般用来做版本管理 ext { guavaVersion= "31.0-jre" upyunSdkVersion = "4.2.0" qiniuSdkVersion = "7.2.29" aliyunSdkVersion = "3.11.3" baiduSdkVersion = "0.10.36" qcloudSdkVersion = "5.6.25" minioSdkVersion = "7.1.4" swaggerVersion = "3.0.0" commonsFileUploadVersion = "1.4" commonsLangVersion = "3.10" httpclientVersion = "4.5.12" dataformatYamlVersion = "2.11.0" jgitVersion = "5.9.0.202009080501-r" flexmarkVersion = "0.62.2" thumbnailatorVersion = "0.4.13" image4jVersion = "0.7zensight1" flywayVersion = "7.5.1" h2Version = "1.4.197" levelDbVersion = "0.12" annotationsVersion = "3.0.1u2" zxingVersion = "3.4.0" huaweiObsVersion = "3.19.7" templateInheritanceVersion = "0.4.RELEASE" jsoupVersion = "1.13.1" }
-
//添加需要什么依赖 dependencies { implementation "org.springframework.boot:spring-boot-starter-actuator" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-web" implementation "org.springframework.boot:spring-boot-starter-jetty" implementation "org.springframework.boot:spring-boot-starter-freemarker" implementation 'org.springframework.boot:spring-boot-starter-validation' implementation "com.sun.mail:jakarta.mail" implementation "com.google.guava:guava:$guavaVersion" implementation "com.upyun:java-sdk:$upyunSdkVersion" implementation "com.qiniu:qiniu-java-sdk:$qiniuSdkVersion" implementation "com.aliyun.oss:aliyun-sdk-oss:$aliyunSdkVersion" implementation "com.baidubce:bce-java-sdk:$baiduSdkVersion" implementation "com.qcloud:cos_api:$qcloudSdkVersion" implementation "com.huaweicloud:esdk-obs-java:$huaweiObsVersion" implementation "io.minio:minio:$minioSdkVersion" implementation "io.springfox:springfox-boot-starter:$swaggerVersion" implementation "commons-fileupload:commons-fileupload:$commonsFileUploadVersion" implementation "org.apache.commons:commons-lang3:$commonsLangVersion" implementation "org.apache.httpcomponents:httpclient:$httpclientVersion" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$dataformatYamlVersion" implementation "org.eclipse.jgit:org.eclipse.jgit:$jgitVersion" implementation "com.google.code.findbugs:annotations:$annotationsVersion" implementation "com.vladsch.flexmark:flexmark:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-attributes:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-autolink:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-emoji:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-escaped-character:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-gfm-tasklist:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-ins:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-media-tags:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-tables:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-toc:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-superscript:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-yaml-front-matter:$flexmarkVersion" implementation "com.vladsch.flexmark:flexmark-ext-gitlab:$flexmarkVersion" implementation "kr.pe.kwonnam.freemarker:freemarker-template-inheritance:$templateInheritanceVersion" implementation "net.coobird:thumbnailator:$thumbnailatorVersion" implementation "net.sf.image4j:image4j:$image4jVersion" implementation "org.flywaydb:flyway-core:$flywayVersion" implementation "com.google.zxing:core:$zxingVersion" implementation "org.iq80.leveldb:leveldb:$levelDbVersion" runtimeOnly "com.h2database:h2:$h2Version" runtimeOnly "mysql:mysql-connector-java" compileOnly "org.projectlombok:lombok" annotationProcessor "org.projectlombok:lombok" testCompileOnly "org.projectlombok:lombok" testAnnotationProcessor "org.projectlombok:lombok" testImplementation("org.springframework.boot:spring-boot-starter-test") { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } testImplementation("org.jsoup:jsoup:${jsoupVersion}") developmentOnly "org.springframework.boot:spring-boot-devtools" }
-
//测试时的配置 test { useJUnitPlatform() testLogging.showStandardStreams = true } task projectVersion { description = 'Prints current project version.' doLast { println project.version } }