This commit is contained in:
2025-11-28 16:23:32 +08:00
commit a9e0e16c29
826 changed files with 89805 additions and 0 deletions

49
blade-core-launch/pom.xml Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>BladeX-Tool</artifactId>
<groupId>org.springblade</groupId>
<version>${revision}</version>
</parent>
<artifactId>blade-core-launch</artifactId>
<name>${project.artifactId}</name>
<version>${project.parent.version}</version>
<packaging>jar</packaging>
<dependencies>
<!--Spring-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
<!-- Auto -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-auto</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,223 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.launch.constant.NacosConstant;
import org.springblade.core.launch.service.LauncherService;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* BladeX 应用启动类
* <p>
* 该类主要封装启动逻辑,包括环境变量处理、配置属性设置、以及自定义组件的加载。
*
* @author BladeX
*/
public class BladeApplication {
/**
* 启动SpringBoot应用不使用自定义SpringApplicationBuilder
*
* @param appName 应用名称
* @param source Spring Boot应用的主类
* @param args 命令行参数
* @return 配置完成的应用上下文
*/
public static ConfigurableApplicationContext run(String appName, Class<?> source, String... args) {
SpringApplicationBuilder springApplicationBuilder = createSpringApplicationBuilder(appName, source, args);
return springApplicationBuilder.run(args);
}
/**
* 启动SpringBoot应用使用自定义SpringApplicationBuilder
*
* @param appName 应用名称
* @param source Spring Boot应用的主类
* @param builder 自定义的SpringApplicationBuilder
* @param args 命令行参数
* @return 配置完成的应用上下文
*/
public static ConfigurableApplicationContext run(String appName, Class<?> source, SpringApplicationBuilder builder, String... args) {
SpringApplicationBuilder springApplicationBuilder = createSpringApplicationBuilder(appName, source, builder, args);
return springApplicationBuilder.run(args);
}
/**
* 创建SpringApplicationBuilder实例包括环境配置、系统属性设置、默认属性设置和自定义组件加载
*
* @param appName 应用名称
* @param source Spring Boot应用的主类
* @param args 命令行参数
* @return 配置完成的SpringApplicationBuilder实例
*/
public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class<?> source, String... args) {
return createSpringApplicationBuilder(appName, source, null, args);
}
/**
* 创建SpringApplicationBuilder实例包括环境配置、系统属性设置、默认属性设置和自定义组件加载
*
* @param appName 应用名称
* @param source Spring Boot应用的主类
* @param builder 自定义的SpringApplicationBuilder
* @param args 命令行参数
* @return 配置完成的SpringApplicationBuilder实例
*/
public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class<?> source, SpringApplicationBuilder builder, String... args) {
Assert.hasText(appName, "[appName]服务名不能为空"); // 确保应用名称不为空
ConfigurableEnvironment environment = configureEnvironment(args); // 配置环境变量,包括命令行参数、系统属性和系统环境变量
List<String> activeProfileList = getActiveProfiles(environment); // 获取当前激活的Spring配置文件列表
String profile = determineActiveProfile(activeProfileList); // 确定要激活的配置文件,如果存在多个则抛出异常
if (builder == null) { // 如果没有提供自定义的SpringApplicationBuilder则创建一个新的
builder = new SpringApplicationBuilder(source); // 使用Spring Boot应用的主类初始化SpringApplicationBuilder
}
builder.profiles(profile); // 设置SpringApplicationBuilder要激活的配置文件
setSystemProperties(appName, profile); // 设置系统属性,包括应用名称、激活的配置文件等
Properties defaultProperties = setDefaultProperties(appName, profile); // 设置默认的一些属性
builder.properties(defaultProperties); // 将这些默认属性添加到SpringApplicationBuilder中
loadCustomComponents(builder, appName, profile); // 加载自定义组件,如各种启动器服务
return builder; // 返回配置好的SpringApplicationBuilder实例
}
/**
* 判断是否为本地开发环境
*
* @return true如果是本地开发环境否则为false
*/
public static boolean isLocalDev() {
String osName = System.getProperty("os.name");
return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equalsIgnoreCase(osName));
}
/**
* 配置环境变量
*
* @param args 命令行参数
* @return 配置完成的环境
*/
private static ConfigurableEnvironment configureEnvironment(String... args) {
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addFirst(new SimpleCommandLinePropertySource(args));
propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment()));
return environment;
}
/**
* 获取激活的配置文件列表
*
* @param environment 环境配置
* @return 激活的配置文件列表
*/
private static List<String> getActiveProfiles(ConfigurableEnvironment environment) {
String[] activeProfiles = environment.getActiveProfiles();
return new ArrayList<>(Arrays.asList(activeProfiles));
}
/**
* 确定激活的配置文件
*
* @param activeProfileList 激活的配置文件列表
* @return 确定的激活配置文件
*/
private static String determineActiveProfile(List<String> activeProfileList) {
if (activeProfileList.isEmpty()) {
String defaultProfile = AppConstant.DEV_CODE;
activeProfileList.add(defaultProfile);
return defaultProfile;
} else if (activeProfileList.size() == 1) {
return activeProfileList.get(0);
} else {
throw new IllegalStateException("不可同时存在多个环境变量: " + String.join(", ", activeProfileList));
}
}
/**
* 设置系统属性
*
* @param appName 应用名称
* @param profile 激活的配置文件
*/
private static void setSystemProperties(String appName, String profile) {
Properties props = System.getProperties();
props.setProperty("spring.application.name", appName);
props.setProperty("spring.profiles.active", profile);
props.setProperty("info.version", AppConstant.APPLICATION_VERSION);
props.setProperty("info.desc", appName);
props.setProperty("file.encoding", StandardCharsets.UTF_8.name());
props.setProperty("blade.env", profile);
props.setProperty("blade.name", appName);
props.setProperty("blade.is-local", String.valueOf(isLocalDev()));
props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
props.setProperty("loadbalancer.client.name", appName);
}
/**
* 设置默认属性
*
* @param appName 应用名称
* @param profile 激活的配置文件
* @return 默认属性集
*/
private static Properties setDefaultProperties(String appName, String profile) {
Properties defaultProperties = new Properties();
defaultProperties.setProperty("nacos.logging.default.config.enabled", "false");
defaultProperties.setProperty("spring.main.allow-bean-definition-overriding", "true");
defaultProperties.setProperty("spring.sleuth.sampler.percentage", "1.0");
defaultProperties.setProperty("spring.cloud.alibaba.seata.tx-service-group", appName.concat(NacosConstant.NACOS_GROUP_SUFFIX));
defaultProperties.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].data-id", NacosConstant.sharedDataId());
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].group", NacosConstant.NACOS_CONFIG_GROUP);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[0].refresh", NacosConstant.NACOS_CONFIG_REFRESH);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].data-id", NacosConstant.sharedDataId(profile));
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].group", NacosConstant.NACOS_CONFIG_GROUP);
defaultProperties.setProperty("spring.cloud.nacos.config.shared-configs[1].refresh", NacosConstant.NACOS_CONFIG_REFRESH);
return defaultProperties;
}
/**
* 加载自定义组件
*
* @param builder SpringApplicationBuilder实例
* @param appName 应用名称
* @param profile 激活的配置文件
*/
private static void loadCustomComponents(SpringApplicationBuilder builder, String appName, String profile) {
ServiceLoader<LauncherService> serviceLoader = ServiceLoader.load(LauncherService.class);
serviceLoader.forEach(launcherService -> launcherService.launcher(builder, appName, profile, isLocalDev()));
}
}

View File

@@ -0,0 +1,58 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* 项目启动事件通知
*
* @author Chill
*/
@Slf4j
@AutoConfiguration
public class StartEventListener {
@Async
@Order
@EventListener(WebServerInitializedEvent.class)
public void afterStart(WebServerInitializedEvent event) {
Environment environment = event.getApplicationContext().getEnvironment();
String appName = Objects.requireNonNull(environment.getProperty("spring.application.name")).toUpperCase();
int localPort = event.getWebServer().getPort();
String profile = StringUtils.arrayToCommaDelimitedString(environment.getActiveProfiles());
log.info("---[{}]---启动完成,当前使用的端口:[{}],环境变量:[{}]---", appName, localPort, profile);
}
}

View File

@@ -0,0 +1,43 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.config;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* 配置类
*
* @author Chill
*/
@AutoConfiguration
@AllArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class BladeLaunchConfiguration {
}

View File

@@ -0,0 +1,52 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.core.launch.config;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.props.BladePropertySourcePostProcessor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* blade property config
*
* @author L.cm
*/
@AutoConfiguration
@Order(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(BladeProperties.class)
public class BladePropertyConfiguration {
@Bean
public BladePropertySourcePostProcessor bladePropertySourcePostProcessor() {
return new BladePropertySourcePostProcessor();
}
}

View File

@@ -0,0 +1,144 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* 系统常量
*
* @author Chill
*/
public interface AppConstant {
/**
* 应用版本
*/
String APPLICATION_VERSION = "4.0.1.RELEASE";
/**
* 基础包
*/
String BASE_PACKAGES = "org.springblade";
/**
* 应用名前缀
*/
String APPLICATION_NAME_PREFIX = "blade-";
/**
* 网关模块名称
*/
String APPLICATION_GATEWAY_NAME = APPLICATION_NAME_PREFIX + "gateway";
/**
* 授权模块名称
*/
String APPLICATION_AUTH_NAME = APPLICATION_NAME_PREFIX + "auth";
/**
* 监控模块名称
*/
String APPLICATION_ADMIN_NAME = APPLICATION_NAME_PREFIX + "admin";
/**
* 报表系统名称
*/
String APPLICATION_REPORT_NAME = APPLICATION_NAME_PREFIX + "report";
/**
* 集群监控名称
*/
String APPLICATION_TURBINE_NAME = APPLICATION_NAME_PREFIX + "turbine";
/**
* 链路追踪名称
*/
String APPLICATION_ZIPKIN_NAME = APPLICATION_NAME_PREFIX + "zipkin";
/**
* websocket名称
*/
String APPLICATION_WEBSOCKET_NAME = APPLICATION_NAME_PREFIX + "websocket";
/**
* 首页模块名称
*/
String APPLICATION_DESK_NAME = APPLICATION_NAME_PREFIX + "desk";
/**
* 系统模块名称
*/
String APPLICATION_SYSTEM_NAME = APPLICATION_NAME_PREFIX + "system";
/**
* 用户模块名称
*/
String APPLICATION_USER_NAME = APPLICATION_NAME_PREFIX + "user";
/**
* 日志模块名称
*/
String APPLICATION_LOG_NAME = APPLICATION_NAME_PREFIX + "log";
/**
* 开发模块名称
*/
String APPLICATION_DEVELOP_NAME = APPLICATION_NAME_PREFIX + "develop";
/**
* 流程设计器模块名称
*/
String APPLICATION_FLOWDESIGN_NAME = APPLICATION_NAME_PREFIX + "flowdesign";
/**
* 工作流模块名称
*/
String APPLICATION_FLOW_NAME = APPLICATION_NAME_PREFIX + "flow";
/**
* 资源模块名称
*/
String APPLICATION_RESOURCE_NAME = APPLICATION_NAME_PREFIX + "resource";
/**
* 接口文档模块名称
*/
String APPLICATION_SWAGGER_NAME = APPLICATION_NAME_PREFIX + "swagger";
/**
* 任务模块名称
*/
String APPLICATION_JOB_NAME = APPLICATION_NAME_PREFIX + "job";
/**
* 测试模块名称
*/
String APPLICATION_TEST_NAME = APPLICATION_NAME_PREFIX + "test";
/**
* 演示模块名称
*/
String APPLICATION_DEMO_NAME = APPLICATION_NAME_PREFIX + "demo";
/**
* 开发环境
*/
String DEV_CODE = "dev";
/**
* 生产环境
*/
String PROD_CODE = "prod";
/**
* 测试环境
*/
String TEST_CODE = "test";
/**
* 代码部署于 linux 上,工作默认为 mac 和 Windows
*/
String OS_NAME_LINUX = "LINUX";
}

View File

@@ -0,0 +1,59 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* Consul常量.
*
* @author Chill
*/
public interface ConsulConstant {
/**
* consul dev 地址
*/
String CONSUL_HOST = "http://localhost";
/**
* consul端口
*/
String CONSUL_PORT = "8500";
/**
* consul端口
*/
String CONSUL_CONFIG_FORMAT = "yaml";
/**
* consul端口
*/
String CONSUL_WATCH_DELAY = "1000";
/**
* consul端口
*/
String CONSUL_WATCH_ENABLED = "true";
}

View File

@@ -0,0 +1,40 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* 流程常量.
*
* @author Chill
*/
public interface FlowConstant {
/**
* 任务用户标识前缀
*/
String TASK_USR_PREFIX = "taskUser_";
}

View File

@@ -0,0 +1,137 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* Nacos常量.
*
* @author Chill
*/
public interface NacosConstant {
/**
* nacos 地址
*/
String NACOS_ADDR = "127.0.0.1:8848";
/**
* nacos 配置前缀
*/
String NACOS_CONFIG_PREFIX = "blade";
/**
* nacos 组配置后缀
*/
String NACOS_GROUP_SUFFIX = "-group";
/**
* nacos 配置文件类型
*/
String NACOS_CONFIG_FORMAT = "yaml";
/**
* nacos json配置文件类型
*/
String NACOS_CONFIG_JSON_FORMAT = "json";
/**
* nacos 是否刷新
*/
String NACOS_CONFIG_REFRESH = "true";
/**
* nacos 分组
*/
String NACOS_CONFIG_GROUP = "DEFAULT_GROUP";
/**
* seata 分组
*/
String NACOS_SEATA_GROUP = "SEATA_GROUP";
/**
* 构建服务对应的 dataId
*
* @param appName 服务名
* @return dataId
*/
static String dataId(String appName) {
return appName + "." + NACOS_CONFIG_FORMAT;
}
/**
* 构建服务对应的 dataId
*
* @param appName 服务名
* @param profile 环境变量
* @return dataId
*/
static String dataId(String appName, String profile) {
return dataId(appName, profile, NACOS_CONFIG_FORMAT);
}
/**
* 构建服务对应的 dataId
*
* @param appName 服务名
* @param profile 环境变量
* @param format 文件类型
* @return dataId
*/
static String dataId(String appName, String profile, String format) {
return appName + "-" + profile + "." + format;
}
/**
* 服务默认加载的配置
*
* @return sharedDataIds
*/
static String sharedDataId() {
return NACOS_CONFIG_PREFIX + "." + NACOS_CONFIG_FORMAT;
}
/**
* 服务默认加载的配置
*
* @param profile 环境变量
* @return sharedDataIds
*/
static String sharedDataId(String profile) {
return NACOS_CONFIG_PREFIX + "-" + profile + "." + NACOS_CONFIG_FORMAT;
}
/**
* 服务默认加载的配置
*
* @param profile 环境变量
* @return sharedDataIds
*/
static String sharedDataIds(String profile) {
return NACOS_CONFIG_PREFIX + "." + NACOS_CONFIG_FORMAT + "," + NACOS_CONFIG_PREFIX + "-" + profile + "." + NACOS_CONFIG_FORMAT;
}
}

View File

@@ -0,0 +1,39 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* sentinel配置.
*
* @author Chill
*/
public interface SentinelConstant {
/**
* sentinel 地址
*/
String SENTINEL_ADDR = "127.0.0.1:8858";
}

View File

@@ -0,0 +1,62 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* Token配置常量.
*
* @author Chill
*/
public interface TokenConstant {
String AVATAR = "avatar";
String HEADER = "Blade-Auth";
String BEARER = "bearer";
String ACCESS_TOKEN = "access_token";
String REFRESH_TOKEN = "refresh_token";
String CLIENT_ACCESS_TOKEN = "client_access_token";
String IMPLICIT_ACCESS_TOKEN = "implicit_access_token";
String TOKEN_TYPE = "token_type";
String EXPIRES_IN = "expires_in";
String ACCOUNT = "account";
String USER_NAME = "user_name";
String NICK_NAME = "nick_name";
String REAL_NAME = "real_name";
String USER_ID = "user_id";
String DEPT_ID = "dept_id";
String POST_ID = "post_id";
String ROLE_ID = "role_id";
String ROLE_NAME = "role_name";
String TENANT_ID = "tenant_id";
String OAUTH_ID = "oauth_id";
String CLIENT_ID = "client_id";
String DETAIL = "detail";
String LICENSE = "license";
String LICENSE_NAME = "powered by bladex";
String DEFAULT_AVATAR = "https://bladex.cn/images/logo.png";
Integer AUTH_LENGTH = 7;
}

View File

@@ -0,0 +1,54 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.constant;
/**
* zookeeper 配置.
*
* @author Chill
*/
public interface ZookeeperConstant {
/**
* zookeeper id
*/
String ZOOKEEPER_ID = "zk";
/**
* zookeeper connect string
*/
String ZOOKEEPER_CONNECT_STRING = "127.0.0.1:2181";
/**
* zookeeper address
*/
String ZOOKEEPER_ADDRESS = "zookeeper://" + ZOOKEEPER_CONNECT_STRING;
/**
* zookeeper root
*/
String ZOOKEEPER_ROOT = "/blade-services";
}

View File

@@ -0,0 +1,123 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.core.launch.log;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 请求日志级别,来源 okHttp
*
* @author L.cm
*/
@Getter
@RequiredArgsConstructor
public enum BladeLogLevel {
/**
* No logs.
*/
NONE(0),
/**
* Logs request and response lines.
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1 (3-byte body)
*
* <-- 200 OK (22ms, 6-byte body)
* }</pre>
*/
BASIC(1),
/**
* Logs request and response lines and their respective headers.
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
* <-- END HTTP
* }</pre>
*/
HEADERS(2),
/**
* Logs request and response lines and their respective headers and bodies (if present).
*
* <p>Example:
* <pre>{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
*
* Hi?
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
*
* Hello!
* <-- END HTTP
* }</pre>
*/
BODY(3);
/**
* 请求日志配置前缀
*/
public static final String REQ_LOG_PROPS_PREFIX = "blade.log.request";
/**
* 控制台日志是否启用
*/
public static final String CONSOLE_LOG_ENABLED_PROP = "blade.log.console.enabled";
/**
* 级别
*/
private final int level;
/**
* 当前版本 小于和等于 比较的版本
*
* @param level LogLevel
* @return 是否小于和等于
*/
public boolean lte(BladeLogLevel level) {
return this.level <= level.level;
}
}

View File

@@ -0,0 +1,263 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.props;
import lombok.Getter;
import org.springblade.core.launch.constant.AppConstant;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 配置文件
*
* @author Chill
*/
@ConfigurationProperties("blade")
public class BladeProperties implements EnvironmentAware, EnvironmentCapable {
@Nullable
private Environment environment;
/**
* 装载自定义配置blade.prop.xxx
*/
@Getter
private final Map<String, String> prop = new HashMap<>();
/**
* 获取配置
*
* @param key key
* @return value
*/
@Nullable
public String get(String key) {
return get(key, null);
}
/**
* 获取配置
*
* @param key key
* @param defaultValue 默认值
* @return value
*/
@Nullable
public String get(String key, @Nullable String defaultValue) {
String value = prop.get(key);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* 获取配置
*
* @param key key
* @return int value
*/
@Nullable
public Integer getInt(String key) {
return getInt(key, null);
}
/**
* 获取配置
*
* @param key key
* @param defaultValue 默认值
* @return int value
*/
@Nullable
public Integer getInt(String key, @Nullable Integer defaultValue) {
String value = prop.get(key);
if (value != null) {
return Integer.valueOf(value.trim());
}
return defaultValue;
}
/**
* 获取配置
*
* @param key key
* @return long value
*/
@Nullable
public Long getLong(String key) {
return getLong(key, null);
}
/**
* 获取配置
*
* @param key key
* @param defaultValue 默认值
* @return long value
*/
@Nullable
public Long getLong(String key, @Nullable Long defaultValue) {
String value = prop.get(key);
if (value != null) {
return Long.valueOf(value.trim());
}
return defaultValue;
}
/**
* 获取配置
*
* @param key key
* @return Boolean value
*/
@Nullable
public Boolean getBoolean(String key) {
return getBoolean(key, null);
}
/**
* 获取配置
*
* @param key key
* @param defaultValue 默认值
* @return Boolean value
*/
@Nullable
public Boolean getBoolean(String key, @Nullable Boolean defaultValue) {
String value = prop.get(key);
if (value != null) {
value = value.toLowerCase().trim();
return Boolean.parseBoolean(value);
}
return defaultValue;
}
/**
* 获取配置
*
* @param key key
* @return double value
*/
@Nullable
public Double getDouble(String key) {
return getDouble(key, null);
}
/**
* 获取配置
*
* @param key key
* @param defaultValue 默认值
* @return double value
*/
@Nullable
public Double getDouble(String key, @Nullable Double defaultValue) {
String value = prop.get(key);
if (value != null) {
return Double.parseDouble(value.trim());
}
return defaultValue;
}
/**
* 判断是否存在key
*
* @param key prop key
* @return boolean
*/
public boolean containsKey(String key) {
return prop.containsKey(key);
}
/**
* 环境,方便在代码中获取
*
* @return 环境 env
*/
public String getEnv() {
Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null");
String env = environment.getProperty("blade.env");
Assert.notNull(env, "请使用 BladeApplication 启动...");
return env;
}
/**
* 是否是开发环境
*
* @return boolean
*/
public boolean isDev() {
return AppConstant.DEV_CODE.equals(getEnv());
}
/**
* 是否是生产环境
*
* @return boolean
*/
public boolean isProd() {
return AppConstant.PROD_CODE.equals(getEnv());
}
/**
* 是否是测试环境
*
* @return boolean
*/
public boolean isTest() {
return AppConstant.TEST_CODE.equals(getEnv());
}
/**
* 应用名称${spring.application.name}
*
* @return 应用名
*/
public String getName() {
Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null");
return environment.getProperty("spring.application.name", environment.getProperty("blade.name", ""));
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public Environment getEnvironment() {
Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null");
return this.environment;
}
}

View File

@@ -0,0 +1,65 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.core.launch.props;
import org.springframework.core.Ordered;
import java.lang.annotation.*;
/**
* 自定义资源文件读取,优先级最低
*
* @author L.cm
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BladePropertySource {
/**
* Indicate the resource location(s) of the properties file to be loaded.
* for example, {@code "classpath:/com/example/app.yml"}
*
* @return location(s)
*/
String value();
/**
* load app-{activeProfile}.yml
*
* @return {boolean}
*/
boolean loadActiveProfile() default true;
/**
* Get the order value of this resource.
*
* @return order
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}

View File

@@ -0,0 +1,188 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.core.launch.props;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 自定义资源文件读取,优先级最低
*
* @author L.cm
*/
@Slf4j
public class BladePropertySourcePostProcessor implements BeanFactoryPostProcessor, InitializingBean, Ordered {
private final ResourceLoader resourceLoader;
private final List<PropertySourceLoader> propertySourceLoaders;
public BladePropertySourcePostProcessor() {
this.resourceLoader = new DefaultResourceLoader();
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
log.info("BladePropertySourcePostProcessor process @BladePropertySource bean.");
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(BladePropertySource.class);
Set<Map.Entry<String, Object>> beanEntrySet = beansWithAnnotation.entrySet();
// 没有 @YmlPropertySource 注解,跳出
if (beanEntrySet.isEmpty()) {
log.warn("Not found @BladePropertySource on spring bean class.");
return;
}
// 组装资源
List<PropertyFile> propertyFileList = new ArrayList<>();
for (Map.Entry<String, Object> entry : beanEntrySet) {
Class<?> beanClass = ClassUtils.getUserClass(entry.getValue());
BladePropertySource propertySource = AnnotationUtils.getAnnotation(beanClass, BladePropertySource.class);
if (propertySource == null) {
continue;
}
int order = propertySource.order();
boolean loadActiveProfile = propertySource.loadActiveProfile();
String location = propertySource.value();
propertyFileList.add(new PropertyFile(order, location, loadActiveProfile));
}
// 装载 PropertySourceLoader
Map<String, PropertySourceLoader> loaderMap = new HashMap<>(16);
for (PropertySourceLoader loader : propertySourceLoaders) {
String[] loaderExtensions = loader.getFileExtensions();
for (String extension : loaderExtensions) {
loaderMap.put(extension, loader);
}
}
// 去重,排序
List<PropertyFile> sortedPropertyList = propertyFileList.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
ConfigurableEnvironment environment = beanFactory.getBean(ConfigurableEnvironment.class);
MutablePropertySources propertySources = environment.getPropertySources();
// 只支持 activeProfiles没有必要支持 spring.profiles.include。
String[] activeProfiles = environment.getActiveProfiles();
ArrayList<PropertySource> propertySourceList = new ArrayList<>();
for (String profile : activeProfiles) {
for (PropertyFile propertyFile : sortedPropertyList) {
// 不加载 ActiveProfile 的配置文件
if (!propertyFile.loadActiveProfile) {
continue;
}
String extension = propertyFile.getExtension();
PropertySourceLoader loader = loaderMap.get(extension);
if (loader == null) {
throw new IllegalArgumentException("Can't find PropertySourceLoader for PropertySource extension:" + extension);
}
String location = propertyFile.getLocation();
String filePath = StringUtils.stripFilenameExtension(location);
String profiledLocation = filePath + "-" + profile + "." + extension;
Resource resource = resourceLoader.getResource(profiledLocation);
loadPropertySource(profiledLocation, resource, loader, propertySourceList);
}
}
// 本身的 Resource
for (PropertyFile propertyFile : sortedPropertyList) {
String extension = propertyFile.getExtension();
PropertySourceLoader loader = loaderMap.get(extension);
String location = propertyFile.getLocation();
Resource resource = resourceLoader.getResource(location);
loadPropertySource(location, resource, loader, propertySourceList);
}
// 转存
for (PropertySource propertySource : propertySourceList) {
propertySources.addLast(propertySource);
}
}
private static void loadPropertySource(String location, Resource resource,
PropertySourceLoader loader,
List<PropertySource> sourceList) {
if (resource.exists()) {
String name = "bladePropertySource: [" + location + "]";
try {
sourceList.addAll(loader.load(name, resource));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("BladePropertySourcePostProcessor init.");
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
@Getter
@ToString
@EqualsAndHashCode
private static class PropertyFile implements Comparable<PropertyFile> {
private final int order;
private final String location;
private final String extension;
private final boolean loadActiveProfile;
PropertyFile(int order, String location, boolean loadActiveProfile) {
this.order = order;
this.location = location;
this.loadActiveProfile = loadActiveProfile;
this.extension = Objects.requireNonNull(StringUtils.getFilenameExtension(location));
}
@Override
public int compareTo(PropertyFile other) {
return Integer.compare(this.order, other.order);
}
}
}

View File

@@ -0,0 +1,61 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.server;
import lombok.Getter;
import org.springblade.core.launch.utils.INetUtil;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.web.ServerProperties;
/**
* 服务器信息
*
* @author Chill
*/
@Getter
@AutoConfiguration
public class ServerInfo implements SmartInitializingSingleton {
private final ServerProperties serverProperties;
private String hostName;
private String ip;
private Integer port;
private String ipWithPort;
@Autowired(required = false)
public ServerInfo(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Override
public void afterSingletonsInstantiated() {
this.hostName = INetUtil.getHostName();
this.ip = INetUtil.getHostIp();
this.port = serverProperties.getPort();
this.ipWithPort = String.format("%s:%d", ip, port);
}
}

View File

@@ -0,0 +1,69 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.service;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.core.Ordered;
/**
* launcher 扩展 用于一些组件发现
*
* @author Chill
*/
public interface LauncherService extends Ordered, Comparable<LauncherService> {
/**
* 启动时 处理 SpringApplicationBuilder
*
* @param builder SpringApplicationBuilder
* @param appName SpringApplicationAppName
* @param profile SpringApplicationProfile
* @param isLocalDev SpringApplicationIsLocalDev
*/
void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev);
/**
* 获取排列顺序
*
* @return order
*/
@Override
default int getOrder() {
return 0;
}
/**
* 对比排序
*
* @param o LauncherService
* @return compare
*/
@Override
default int compareTo(LauncherService o) {
return Integer.compare(this.getOrder(), o.getOrder());
}
}

View File

@@ -0,0 +1,253 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: DreamLu (596392912@qq.com)
*/
package org.springblade.core.launch.utils;
import org.springframework.util.ObjectUtils;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.Enumeration;
/**
* INet 相关工具
*
* @author L.cm
*/
public class INetUtil {
public static final String LOCAL_HOST = "127.0.0.1";
/**
* 获取 服务器 hostname
*
* @return hostname
*/
public static String getHostName() {
String hostname;
try {
InetAddress address = InetAddress.getLocalHost();
// force a best effort reverse DNS lookup
hostname = address.getHostName();
if (ObjectUtils.isEmpty(hostname)) {
hostname = address.toString();
}
} catch (UnknownHostException ignore) {
hostname = LOCAL_HOST;
}
return hostname;
}
/**
* 获取 服务器 HostIp
*
* @return HostIp
*/
public static String getHostIp() {
String hostAddress;
try {
InetAddress address = INetUtil.getLocalHostLANAddress();
// force a best effort reverse DNS lookup
hostAddress = address.getHostAddress();
if (ObjectUtils.isEmpty(hostAddress)) {
hostAddress = address.toString();
}
} catch (UnknownHostException ignore) {
hostAddress = LOCAL_HOST;
}
return hostAddress;
}
/**
* https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java
*
* <p>
* Returns an <code>InetAddress</code> object encapsulating what is most likely the machine's LAN IP address.
* <p/>
* This method is intended for use as a replacement of JDK method <code>InetAddress.getLocalHost</code>, because
* that method is ambiguous on Linux systems. Linux systems enumerate the loopback network interface the same
* way as regular LAN network interfaces, but the JDK <code>InetAddress.getLocalHost</code> method does not
* specify the algorithm used to select the address returned under such circumstances, and will often return the
* loopback address, which is not valid for network communication. Details
* <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037">here</a>.
* <p/>
* This method will scan all IP addresses on all network interfaces on the host machine to determine the IP address
* most likely to be the machine's LAN address. If the machine has multiple IP addresses, this method will prefer
* a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually IPv4) if the machine has one (and will return the
* first site-local address if the machine has more than one), but if the machine does not hold a site-local
* address, this method will return simply the first non-loopback address found (IPv4 or IPv6).
* <p/>
* If this method cannot find a non-loopback address using this selection algorithm, it will fall back to
* calling and returning the result of JDK method <code>InetAddress.getLocalHost</code>.
* <p/>
*
* @throws UnknownHostException If the LAN address of the machine cannot be found.
*/
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
// Iterate all NICs (network interface cards)...
for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
// Iterate all IP addresses assigned to each card...
for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) {
if (inetAddr.isSiteLocalAddress()) {
// Found non-loopback site-local address. Return it immediately...
return inetAddr;
} else if (candidateAddress == null) {
// Found non-loopback address, but not necessarily site-local.
// Store it as a candidate to be returned if site-local address is not subsequently found...
candidateAddress = inetAddr;
// Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
// only the first. For subsequent iterations, candidate will be non-null.
}
}
}
}
if (candidateAddress != null) {
// We did not find a site-local address, but we found some other non-loopback address.
// Server might have a non-site-local address assigned to its NIC (or it might be running
// IPv6 which deprecates the "site-local" concept).
// Return this non-loopback candidate address...
return candidateAddress;
}
// At this point, we did not find a non-loopback address.
// Fall back to returning whatever InetAddress.getLocalHost() returns...
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
if (jdkSuppliedAddress == null) {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
}
return jdkSuppliedAddress;
} catch (Exception e) {
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
unknownHostException.initCause(e);
throw unknownHostException;
}
}
/**
* 尝试端口时候被占用
*
* @param port 端口号
* @return 没有被占用true,被占用false
*/
public static boolean tryPort(int port) {
try (ServerSocket ignore = new ServerSocket(port)) {
return true;
} catch (Exception e) {
return false;
}
}
/**
* 将 ip 转成 InetAddress
*
* @param ip ip
* @return InetAddress
*/
public static InetAddress getInetAddress(String ip) {
try {
return InetAddress.getByName(ip);
} catch (UnknownHostException e) {
return null;
}
}
/**
* 判断是否内网 ip
*
* @param ip ip
* @return boolean
*/
public static boolean isInternalIp(String ip) {
return isInternalIp(getInetAddress(ip));
}
/**
* 判断是否内网 ip
*
* @param address InetAddress
* @return boolean
*/
public static boolean isInternalIp(InetAddress address) {
if (isLocalIp(address)) {
return true;
}
return isInternalIp(address.getAddress());
}
/**
* 判断是否本地 ip
*
* @param address InetAddress
* @return boolean
*/
public static boolean isLocalIp(InetAddress address) {
return address.isAnyLocalAddress()
|| address.isLoopbackAddress()
|| address.isSiteLocalAddress();
}
/**
* 判断是否内网 ip
*
* @param addr ip
* @return boolean
*/
public static boolean isInternalIp(byte[] addr) {
final byte b0 = addr[0];
final byte b1 = addr[1];
//10.x.x.x/8
final byte section1 = 0x0A;
//172.16.x.x/12
final byte section2 = (byte) 0xAC;
final byte section3 = (byte) 0x10;
final byte section4 = (byte) 0x1F;
//192.168.x.x/16
final byte section5 = (byte) 0xC0;
final byte section6 = (byte) 0xA8;
switch (b0) {
case section1:
return true;
case section2:
if (b1 >= section3 && b1 <= section4) {
return true;
}
case section5:
if (b1 == section6) {
return true;
}
default:
return false;
}
}
}

View File

@@ -0,0 +1,52 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.launch.utils;
import org.springframework.util.ObjectUtils;
import java.util.Properties;
/**
* 配置工具类
*
* @author Chill
*/
public class PropsUtil {
/**
* 设置配置值,已存在则跳过
*
* @param props property
* @param key key
* @param value value
*/
public static void setProperty(Properties props, String key, String value) {
if (ObjectUtils.isEmpty(props.getProperty(key))) {
props.setProperty(key, value);
}
}
}